Hex Artifact Content
Logged in as anonymous

Artifact ae3b49a3678b3fd2b5bccd5fba68084de50f2b444457a2c2975727afbcbd7083:


0000: 75 73 65 20 73 74 64 3a 3a 7b 0a 09 62 6f 72 72  use std::{..borr
0010: 6f 77 3a 3a 43 6f 77 2c 0a 09 66 6d 74 2c 0a 7d  ow::Cow,..fmt,.}
0020: 3b 0a 0a 75 73 65 20 61 6e 79 68 6f 77 3a 3a 7b  ;..use anyhow::{
0030: 0a 09 52 65 73 75 6c 74 2c 0a 09 62 61 69 6c 2c  ..Result,..bail,
0040: 0a 7d 3b 0a 75 73 65 20 61 73 79 6e 63 5f 73 74  .};.use async_st
0050: 64 3a 3a 73 79 6e 63 3a 3a 7b 0a 09 41 72 63 2c  d::sync::{..Arc,
0060: 0a 09 4d 75 74 65 78 2c 0a 7d 3b 0a 75 73 65 20  ..Mutex,.};.use 
0070: 63 68 72 6f 6e 6f 3a 3a 7b 0a 09 44 61 74 65 54  chrono::{..DateT
0080: 69 6d 65 2c 0a 09 46 69 78 65 64 4f 66 66 73 65  ime,..FixedOffse
0090: 74 2c 0a 09 4c 6f 63 61 6c 2c 0a 7d 3b 0a 75 73  t,..Local,.};.us
00a0: 65 20 73 71 6c 78 3a 3a 7b 0a 09 50 6f 73 74 67  e sqlx::{..Postg
00b0: 72 65 73 2c 0a 09 52 6f 77 2c 0a 09 70 6f 73 74  res,..Row,..post
00c0: 67 72 65 73 3a 3a 50 67 50 6f 6f 6c 4f 70 74 69  gres::PgPoolOpti
00d0: 6f 6e 73 2c 0a 09 70 6f 6f 6c 3a 3a 50 6f 6f 6c  ons,..pool::Pool
00e0: 43 6f 6e 6e 65 63 74 69 6f 6e 2c 0a 7d 3b 0a 0a  Connection,.};..
00f0: 23 5b 64 65 72 69 76 65 28 73 71 6c 78 3a 3a 46  #[derive(sqlx::F
0100: 72 6f 6d 52 6f 77 2c 20 44 65 62 75 67 29 5d 0a  romRow, Debug)].
0110: 70 75 62 20 73 74 72 75 63 74 20 4c 69 73 74 20  pub struct List 
0120: 7b 0a 09 70 75 62 20 73 6f 75 72 63 65 5f 69 64  {..pub source_id
0130: 3a 20 69 33 32 2c 0a 09 70 75 62 20 63 68 61 6e  : i32,..pub chan
0140: 6e 65 6c 3a 20 53 74 72 69 6e 67 2c 0a 09 70 75  nel: String,..pu
0150: 62 20 65 6e 61 62 6c 65 64 3a 20 62 6f 6f 6c 2c  b enabled: bool,
0160: 0a 09 70 75 62 20 75 72 6c 3a 20 53 74 72 69 6e  ..pub url: Strin
0170: 67 2c 0a 09 70 75 62 20 69 76 5f 68 61 73 68 3a  g,..pub iv_hash:
0180: 20 4f 70 74 69 6f 6e 3c 53 74 72 69 6e 67 3e 2c   Option<String>,
0190: 0a 09 70 75 62 20 75 72 6c 5f 72 65 3a 20 4f 70  ..pub url_re: Op
01a0: 74 69 6f 6e 3c 53 74 72 69 6e 67 3e 2c 0a 7d 0a  tion<String>,.}.
01b0: 0a 69 6d 70 6c 20 66 6d 74 3a 3a 44 69 73 70 6c  .impl fmt::Displ
01c0: 61 79 20 66 6f 72 20 4c 69 73 74 20 7b 0a 09 66  ay for List {..f
01d0: 6e 20 66 6d 74 28 26 73 65 6c 66 2c 20 66 3a 20  n fmt(&self, f: 
01e0: 26 6d 75 74 20 66 6d 74 3a 3a 46 6f 72 6d 61 74  &mut fmt::Format
01f0: 74 65 72 3c 27 5f 3e 29 20 2d 3e 20 52 65 73 75  ter<'_>) -> Resu
0200: 6c 74 3c 28 29 2c 20 66 6d 74 3a 3a 45 72 72 6f  lt<(), fmt::Erro
0210: 72 3e 20 7b 0a 09 09 77 72 69 74 65 21 28 66 2c  r> {...write!(f,
0220: 20 22 5c 5c 23 ef b8 8f e2 83 a3 20 7b 7d 20 5c   "\\#ļøāƒ£ {} \
0230: 5c 2a ef b8 8f e2 83 a3 20 60 7b 7d 60 20 7b 7d  \*ļøāƒ£ `{}` {}
0240: 5c 6e f0 9f 94 97 20 60 7b 7d 60 22 2c 20 73 65  \nšŸ”— `{}`", se
0250: 6c 66 2e 73 6f 75 72 63 65 5f 69 64 2c 20 73 65  lf.source_id, se
0260: 6c 66 2e 63 68 61 6e 6e 65 6c 2c 0a 09 09 09 6d  lf.channel,....m
0270: 61 74 63 68 20 73 65 6c 66 2e 65 6e 61 62 6c 65  atch self.enable
0280: 64 20 7b 0a 09 09 09 09 74 72 75 65 20 20 3d 3e  d {.....true  =>
0290: 20 22 f0 9f 94 84 20 65 6e 61 62 6c 65 64 22 2c   "šŸ”„ enabled",
02a0: 0a 09 09 09 09 66 61 6c 73 65 20 3d 3e 20 22 e2  .....false => "ā
02b0: 9b 94 20 64 69 73 61 62 6c 65 64 22 2c 0a 09 09  ›” disabled",...
02c0: 09 7d 2c 20 73 65 6c 66 2e 75 72 6c 29 3f 3b 0a  .}, self.url)?;.
02d0: 09 09 69 66 20 6c 65 74 20 53 6f 6d 65 28 69 76  ..if let Some(iv
02e0: 5f 68 61 73 68 29 20 3d 20 26 73 65 6c 66 2e 69  _hash) = &self.i
02f0: 76 5f 68 61 73 68 20 7b 0a 09 09 09 77 72 69 74  v_hash {....writ
0300: 65 21 28 66 2c 20 22 5c 6e 49 56 3a 20 60 7b 69  e!(f, "\nIV: `{i
0310: 76 5f 68 61 73 68 7d 60 22 29 3f 3b 0a 09 09 7d  v_hash}`")?;...}
0320: 0a 09 09 69 66 20 6c 65 74 20 53 6f 6d 65 28 75  ...if let Some(u
0330: 72 6c 5f 72 65 29 20 3d 20 26 73 65 6c 66 2e 75  rl_re) = &self.u
0340: 72 6c 5f 72 65 20 7b 0a 09 09 09 77 72 69 74 65  rl_re {....write
0350: 21 28 66 2c 20 22 5c 6e 52 45 3a 20 60 7b 75 72  !(f, "\nRE: `{ur
0360: 6c 5f 72 65 7d 60 22 29 3f 3b 0a 09 09 7d 0a 09  l_re}`")?;...}..
0370: 09 4f 6b 28 28 29 29 0a 09 7d 0a 7d 0a 0a 23 5b  .Ok(())..}.}..#[
0380: 64 65 72 69 76 65 28 73 71 6c 78 3a 3a 46 72 6f  derive(sqlx::Fro
0390: 6d 52 6f 77 2c 20 44 65 62 75 67 29 5d 0a 70 75  mRow, Debug)].pu
03a0: 62 20 73 74 72 75 63 74 20 53 6f 75 72 63 65 20  b struct Source 
03b0: 7b 0a 09 70 75 62 20 63 68 61 6e 6e 65 6c 5f 69  {..pub channel_i
03c0: 64 3a 20 69 36 34 2c 0a 09 70 75 62 20 75 72 6c  d: i64,..pub url
03d0: 3a 20 53 74 72 69 6e 67 2c 0a 09 70 75 62 20 69  : String,..pub i
03e0: 76 5f 68 61 73 68 3a 20 4f 70 74 69 6f 6e 3c 53  v_hash: Option<S
03f0: 74 72 69 6e 67 3e 2c 0a 09 70 75 62 20 6f 77 6e  tring>,..pub own
0400: 65 72 3a 20 69 36 34 2c 0a 09 70 75 62 20 75 72  er: i64,..pub ur
0410: 6c 5f 72 65 3a 20 4f 70 74 69 6f 6e 3c 53 74 72  l_re: Option<Str
0420: 69 6e 67 3e 2c 0a 7d 0a 0a 23 5b 64 65 72 69 76  ing>,.}..#[deriv
0430: 65 28 73 71 6c 78 3a 3a 46 72 6f 6d 52 6f 77 29  e(sqlx::FromRow)
0440: 5d 0a 70 75 62 20 73 74 72 75 63 74 20 51 75 65  ].pub struct Que
0450: 75 65 20 7b 0a 09 70 75 62 20 73 6f 75 72 63 65  ue {..pub source
0460: 5f 69 64 3a 20 4f 70 74 69 6f 6e 3c 69 33 32 3e  _id: Option<i32>
0470: 2c 0a 09 70 75 62 20 6e 65 78 74 5f 66 65 74 63  ,..pub next_fetc
0480: 68 3a 20 4f 70 74 69 6f 6e 3c 44 61 74 65 54 69  h: Option<DateTi
0490: 6d 65 3c 4c 6f 63 61 6c 3e 3e 2c 0a 09 70 75 62  me<Local>>,..pub
04a0: 20 6f 77 6e 65 72 3a 20 4f 70 74 69 6f 6e 3c 69   owner: Option<i
04b0: 36 34 3e 2c 0a 7d 0a 0a 23 5b 64 65 72 69 76 65  64>,.}..#[derive
04c0: 28 43 6c 6f 6e 65 29 5d 0a 70 75 62 20 73 74 72  (Clone)].pub str
04d0: 75 63 74 20 44 62 20 7b 0a 09 70 6f 6f 6c 3a 20  uct Db {..pool: 
04e0: 41 72 63 3c 4d 75 74 65 78 3c 73 71 6c 78 3a 3a  Arc<Mutex<sqlx::
04f0: 50 6f 6f 6c 3c 73 71 6c 78 3a 3a 50 6f 73 74 67  Pool<sqlx::Postg
0500: 72 65 73 3e 3e 3e 2c 0a 7d 0a 0a 70 75 62 20 73  res>>>,.}..pub s
0510: 74 72 75 63 74 20 43 6f 6e 6e 7b 0a 09 63 6f 6e  truct Conn{..con
0520: 6e 3a 20 50 6f 6f 6c 43 6f 6e 6e 65 63 74 69 6f  n: PoolConnectio
0530: 6e 3c 50 6f 73 74 67 72 65 73 3e 2c 0a 7d 0a 0a  n<Postgres>,.}..
0540: 69 6d 70 6c 20 44 62 20 7b 0a 09 70 75 62 20 66  impl Db {..pub f
0550: 6e 20 6e 65 77 20 28 70 67 75 72 69 3a 20 26 73  n new (pguri: &s
0560: 74 72 29 20 2d 3e 20 52 65 73 75 6c 74 3c 44 62  tr) -> Result<Db
0570: 3e 20 7b 0a 09 09 4f 6b 28 44 62 7b 0a 09 09 09  > {...Ok(Db{....
0580: 70 6f 6f 6c 3a 20 41 72 63 3a 3a 6e 65 77 28 4d  pool: Arc::new(M
0590: 75 74 65 78 3a 3a 6e 65 77 28 50 67 50 6f 6f 6c  utex::new(PgPool
05a0: 4f 70 74 69 6f 6e 73 3a 3a 6e 65 77 28 29 0a 09  Options::new()..
05b0: 09 09 09 2e 6d 61 78 5f 63 6f 6e 6e 65 63 74 69  ....max_connecti
05c0: 6f 6e 73 28 35 29 0a 09 09 09 09 2e 61 63 71 75  ons(5)......acqu
05d0: 69 72 65 5f 74 69 6d 65 6f 75 74 28 73 74 64 3a  ire_timeout(std:
05e0: 3a 74 69 6d 65 3a 3a 44 75 72 61 74 69 6f 6e 3a  :time::Duration:
05f0: 3a 6e 65 77 28 33 30 30 2c 20 30 29 29 0a 09 09  :new(300, 0))...
0600: 09 09 2e 69 64 6c 65 5f 74 69 6d 65 6f 75 74 28  ...idle_timeout(
0610: 73 74 64 3a 3a 74 69 6d 65 3a 3a 44 75 72 61 74  std::time::Durat
0620: 69 6f 6e 3a 3a 6e 65 77 28 36 30 2c 20 30 29 29  ion::new(60, 0))
0630: 0a 09 09 09 09 2e 63 6f 6e 6e 65 63 74 5f 6c 61  ......connect_la
0640: 7a 79 28 70 67 75 72 69 29 3f 29 29 2c 0a 09 09  zy(pguri)?)),...
0650: 7d 29 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79 6e  })..}...pub asyn
0660: 63 20 66 6e 20 62 65 67 69 6e 28 26 73 65 6c 66  c fn begin(&self
0670: 29 20 2d 3e 20 52 65 73 75 6c 74 3c 43 6f 6e 6e  ) -> Result<Conn
0680: 3e 20 7b 0a 09 09 6c 65 74 20 70 6f 6f 6c 20 3d  > {...let pool =
0690: 20 73 65 6c 66 2e 70 6f 6f 6c 2e 6c 6f 63 6b 5f   self.pool.lock_
06a0: 61 72 63 28 29 2e 61 77 61 69 74 3b 0a 09 09 6c  arc().await;...l
06b0: 65 74 20 63 6f 6e 6e 20 3d 20 43 6f 6e 6e 3a 3a  et conn = Conn::
06c0: 6e 65 77 28 70 6f 6f 6c 2e 61 63 71 75 69 72 65  new(pool.acquire
06d0: 28 29 2e 61 77 61 69 74 3f 29 2e 61 77 61 69 74  ().await?).await
06e0: 3f 3b 0a 09 09 4f 6b 28 63 6f 6e 6e 29 0a 09 7d  ?;...Ok(conn)..}
06f0: 0a 7d 0a 0a 69 6d 70 6c 20 43 6f 6e 6e 20 7b 0a  .}..impl Conn {.
0700: 09 70 75 62 20 61 73 79 6e 63 20 66 6e 20 6e 65  .pub async fn ne
0710: 77 20 28 63 6f 6e 6e 3a 20 50 6f 6f 6c 43 6f 6e  w (conn: PoolCon
0720: 6e 65 63 74 69 6f 6e 3c 50 6f 73 74 67 72 65 73  nection<Postgres
0730: 3e 29 20 2d 3e 20 52 65 73 75 6c 74 3c 43 6f 6e  >) -> Result<Con
0740: 6e 3e 20 7b 0a 09 09 4f 6b 28 43 6f 6e 6e 7b 0a  n> {...Ok(Conn{.
0750: 09 09 09 63 6f 6e 6e 2c 0a 09 09 7d 29 0a 09 7d  ...conn,...})..}
0760: 0a 0a 09 70 75 62 20 61 73 79 6e 63 20 66 6e 20  ...pub async fn 
0770: 61 64 64 5f 70 6f 73 74 20 28 26 6d 75 74 20 73  add_post (&mut s
0780: 65 6c 66 2c 20 73 6f 75 72 63 65 5f 69 64 3a 20  elf, source_id: 
0790: 69 33 32 2c 20 64 61 74 65 3a 20 26 44 61 74 65  i32, date: &Date
07a0: 54 69 6d 65 3c 46 69 78 65 64 4f 66 66 73 65 74  Time<FixedOffset
07b0: 3e 2c 20 70 6f 73 74 5f 75 72 6c 3a 20 26 73 74  >, post_url: &st
07c0: 72 29 20 2d 3e 20 52 65 73 75 6c 74 3c 28 29 3e  r) -> Result<()>
07d0: 20 7b 0a 09 09 73 71 6c 78 3a 3a 71 75 65 72 79   {...sqlx::query
07e0: 28 22 69 6e 73 65 72 74 20 69 6e 74 6f 20 72 73  ("insert into rs
07f0: 73 74 67 5f 70 6f 73 74 20 28 73 6f 75 72 63 65  stg_post (source
0800: 5f 69 64 2c 20 70 6f 73 74 65 64 2c 20 75 72 6c  _id, posted, url
0810: 29 20 76 61 6c 75 65 73 20 28 24 31 2c 20 24 32  ) values ($1, $2
0820: 2c 20 24 33 29 3b 22 29 0a 09 09 09 2e 62 69 6e  , $3);").....bin
0830: 64 28 73 6f 75 72 63 65 5f 69 64 29 0a 09 09 09  d(source_id)....
0840: 2e 62 69 6e 64 28 64 61 74 65 29 0a 09 09 09 2e  .bind(date).....
0850: 62 69 6e 64 28 70 6f 73 74 5f 75 72 6c 29 0a 09  bind(post_url)..
0860: 09 09 2e 65 78 65 63 75 74 65 28 26 6d 75 74 20  ...execute(&mut 
0870: 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77 61 69  *self.conn).awai
0880: 74 3f 3b 0a 09 09 4f 6b 28 28 29 29 0a 09 7d 0a  t?;...Ok(())..}.
0890: 0a 09 70 75 62 20 61 73 79 6e 63 20 66 6e 20 63  ..pub async fn c
08a0: 6c 65 61 6e 20 3c 49 3e 20 28 26 6d 75 74 20 73  lean <I> (&mut s
08b0: 65 6c 66 2c 20 73 6f 75 72 63 65 5f 69 64 3a 20  elf, source_id: 
08c0: 69 33 32 2c 20 6f 77 6e 65 72 3a 20 49 29 20 2d  i32, owner: I) -
08d0: 3e 20 52 65 73 75 6c 74 3c 43 6f 77 3c 27 5f 2c  > Result<Cow<'_,
08e0: 20 73 74 72 3e 3e 0a 09 77 68 65 72 65 20 49 3a   str>>..where I:
08f0: 20 49 6e 74 6f 3c 69 36 34 3e 20 7b 0a 09 09 6d   Into<i64> {...m
0900: 61 74 63 68 20 73 71 6c 78 3a 3a 71 75 65 72 79  atch sqlx::query
0910: 28 22 64 65 6c 65 74 65 20 66 72 6f 6d 20 72 73  ("delete from rs
0920: 73 74 67 5f 70 6f 73 74 20 70 20 75 73 69 6e 67  stg_post p using
0930: 20 72 73 73 74 67 5f 73 6f 75 72 63 65 20 73 20   rsstg_source s 
0940: 77 68 65 72 65 20 70 2e 73 6f 75 72 63 65 5f 69  where p.source_i
0950: 64 20 3d 20 24 31 20 61 6e 64 20 6f 77 6e 65 72  d = $1 and owner
0960: 20 3d 20 24 32 20 61 6e 64 20 70 2e 73 6f 75 72   = $2 and p.sour
0970: 63 65 5f 69 64 20 3d 20 73 2e 73 6f 75 72 63 65  ce_id = s.source
0980: 5f 69 64 3b 22 29 0a 09 09 09 2e 62 69 6e 64 28  _id;").....bind(
0990: 73 6f 75 72 63 65 5f 69 64 29 0a 09 09 09 2e 62  source_id).....b
09a0: 69 6e 64 28 6f 77 6e 65 72 2e 69 6e 74 6f 28 29  ind(owner.into()
09b0: 29 0a 09 09 09 2e 65 78 65 63 75 74 65 28 26 6d  ).....execute(&m
09c0: 75 74 20 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61  ut *self.conn).a
09d0: 77 61 69 74 3f 2e 72 6f 77 73 5f 61 66 66 65 63  wait?.rows_affec
09e0: 74 65 64 28 29 20 7b 0a 09 09 09 30 20 3d 3e 20  ted() {....0 => 
09f0: 7b 20 4f 6b 28 22 4e 6f 20 64 61 74 61 20 66 6f  { Ok("No data fo
0a00: 75 6e 64 20 66 6f 75 6e 64 2e 22 2e 69 6e 74 6f  und found.".into
0a10: 28 29 29 20 7d 2c 0a 09 09 09 78 20 3d 3e 20 7b  ()) },....x => {
0a20: 20 4f 6b 28 66 6f 72 6d 61 74 21 28 22 7b 78 7d   Ok(format!("{x}
0a30: 20 70 6f 73 74 73 20 70 75 72 67 65 64 2e 22 29   posts purged.")
0a40: 2e 69 6e 74 6f 28 29 29 20 7d 2c 0a 09 09 7d 0a  .into()) },...}.
0a50: 09 7d 0a 0a 09 70 75 62 20 61 73 79 6e 63 20 66  .}...pub async f
0a60: 6e 20 64 65 6c 65 74 65 20 3c 49 3e 20 28 26 6d  n delete <I> (&m
0a70: 75 74 20 73 65 6c 66 2c 20 73 6f 75 72 63 65 5f  ut self, source_
0a80: 69 64 3a 20 69 33 32 2c 20 6f 77 6e 65 72 3a 20  id: i32, owner: 
0a90: 49 29 20 2d 3e 20 52 65 73 75 6c 74 3c 43 6f 77  I) -> Result<Cow
0aa0: 3c 27 5f 2c 20 73 74 72 3e 3e 0a 09 77 68 65 72  <'_, str>>..wher
0ab0: 65 20 49 3a 20 49 6e 74 6f 3c 69 36 34 3e 20 7b  e I: Into<i64> {
0ac0: 0a 09 09 6d 61 74 63 68 20 73 71 6c 78 3a 3a 71  ...match sqlx::q
0ad0: 75 65 72 79 28 22 64 65 6c 65 74 65 20 66 72 6f  uery("delete fro
0ae0: 6d 20 72 73 73 74 67 5f 73 6f 75 72 63 65 20 77  m rsstg_source w
0af0: 68 65 72 65 20 73 6f 75 72 63 65 5f 69 64 20 3d  here source_id =
0b00: 20 24 31 20 61 6e 64 20 6f 77 6e 65 72 20 3d 20   $1 and owner = 
0b10: 24 32 3b 22 29 0a 09 09 09 2e 62 69 6e 64 28 73  $2;").....bind(s
0b20: 6f 75 72 63 65 5f 69 64 29 0a 09 09 09 2e 62 69  ource_id).....bi
0b30: 6e 64 28 6f 77 6e 65 72 2e 69 6e 74 6f 28 29 29  nd(owner.into())
0b40: 0a 09 09 09 2e 65 78 65 63 75 74 65 28 26 6d 75  .....execute(&mu
0b50: 74 20 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77  t *self.conn).aw
0b60: 61 69 74 3f 2e 72 6f 77 73 5f 61 66 66 65 63 74  ait?.rows_affect
0b70: 65 64 28 29 20 7b 0a 09 09 09 30 20 3d 3e 20 7b  ed() {....0 => {
0b80: 20 4f 6b 28 22 4e 6f 20 64 61 74 61 20 66 6f 75   Ok("No data fou
0b90: 6e 64 20 66 6f 75 6e 64 2e 22 2e 69 6e 74 6f 28  nd found.".into(
0ba0: 29 29 20 7d 2c 0a 09 09 09 78 20 3d 3e 20 7b 20  )) },....x => { 
0bb0: 4f 6b 28 66 6f 72 6d 61 74 21 28 22 7b 7d 20 73  Ok(format!("{} s
0bc0: 6f 75 72 63 65 73 20 72 65 6d 6f 76 65 64 2e 22  ources removed."
0bd0: 2c 20 78 29 2e 69 6e 74 6f 28 29 29 20 7d 2c 0a  , x).into()) },.
0be0: 09 09 7d 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79  ..}..}...pub asy
0bf0: 6e 63 20 66 6e 20 64 69 73 61 62 6c 65 20 3c 49  nc fn disable <I
0c00: 3e 20 28 26 6d 75 74 20 73 65 6c 66 2c 20 73 6f  > (&mut self, so
0c10: 75 72 63 65 5f 69 64 3a 20 69 33 32 2c 20 6f 77  urce_id: i32, ow
0c20: 6e 65 72 3a 20 49 29 20 2d 3e 20 52 65 73 75 6c  ner: I) -> Resul
0c30: 74 3c 26 73 74 72 3e 0a 09 77 68 65 72 65 20 49  t<&str>..where I
0c40: 3a 20 49 6e 74 6f 3c 69 36 34 3e 20 7b 0a 09 09  : Into<i64> {...
0c50: 6d 61 74 63 68 20 73 71 6c 78 3a 3a 71 75 65 72  match sqlx::quer
0c60: 79 28 22 75 70 64 61 74 65 20 72 73 73 74 67 5f  y("update rsstg_
0c70: 73 6f 75 72 63 65 20 73 65 74 20 65 6e 61 62 6c  source set enabl
0c80: 65 64 20 3d 20 66 61 6c 73 65 20 77 68 65 72 65  ed = false where
0c90: 20 73 6f 75 72 63 65 5f 69 64 20 3d 20 24 31 20   source_id = $1 
0ca0: 61 6e 64 20 6f 77 6e 65 72 20 3d 20 24 32 22 29  and owner = $2")
0cb0: 0a 09 09 09 2e 62 69 6e 64 28 73 6f 75 72 63 65  .....bind(source
0cc0: 5f 69 64 29 0a 09 09 09 2e 62 69 6e 64 28 6f 77  _id).....bind(ow
0cd0: 6e 65 72 2e 69 6e 74 6f 28 29 29 0a 09 09 09 2e  ner.into()).....
0ce0: 65 78 65 63 75 74 65 28 26 6d 75 74 20 2a 73 65  execute(&mut *se
0cf0: 6c 66 2e 63 6f 6e 6e 29 2e 61 77 61 69 74 3f 2e  lf.conn).await?.
0d00: 72 6f 77 73 5f 61 66 66 65 63 74 65 64 28 29 20  rows_affected() 
0d10: 7b 0a 09 09 09 31 20 3d 3e 20 7b 20 4f 6b 28 22  {....1 => { Ok("
0d20: 53 6f 75 72 63 65 20 64 69 73 61 62 6c 65 64 2e  Source disabled.
0d30: 22 29 20 7d 2c 0a 09 09 09 30 20 3d 3e 20 7b 20  ") },....0 => { 
0d40: 4f 6b 28 22 53 6f 75 72 63 65 20 6e 6f 74 20 66  Ok("Source not f
0d50: 6f 75 6e 64 2e 22 29 20 7d 2c 0a 09 09 09 5f 20  ound.") },...._ 
0d60: 3d 3e 20 7b 20 62 61 69 6c 21 28 22 44 61 74 61  => { bail!("Data
0d70: 62 61 73 65 20 65 72 72 6f 72 2e 22 29 20 7d 2c  base error.") },
0d80: 0a 09 09 7d 0a 09 7d 0a 0a 09 70 75 62 20 61 73  ...}..}...pub as
0d90: 79 6e 63 20 66 6e 20 65 6e 61 62 6c 65 20 3c 49  ync fn enable <I
0da0: 3e 20 28 26 6d 75 74 20 73 65 6c 66 2c 20 73 6f  > (&mut self, so
0db0: 75 72 63 65 5f 69 64 3a 20 69 33 32 2c 20 6f 77  urce_id: i32, ow
0dc0: 6e 65 72 3a 20 49 29 20 2d 3e 20 52 65 73 75 6c  ner: I) -> Resul
0dd0: 74 3c 26 73 74 72 3e 0a 09 77 68 65 72 65 20 49  t<&str>..where I
0de0: 3a 20 49 6e 74 6f 3c 69 36 34 3e 20 7b 0a 09 09  : Into<i64> {...
0df0: 6d 61 74 63 68 20 73 71 6c 78 3a 3a 71 75 65 72  match sqlx::quer
0e00: 79 28 22 75 70 64 61 74 65 20 72 73 73 74 67 5f  y("update rsstg_
0e10: 73 6f 75 72 63 65 20 73 65 74 20 65 6e 61 62 6c  source set enabl
0e20: 65 64 20 3d 20 74 72 75 65 20 77 68 65 72 65 20  ed = true where 
0e30: 73 6f 75 72 63 65 5f 69 64 20 3d 20 24 31 20 61  source_id = $1 a
0e40: 6e 64 20 6f 77 6e 65 72 20 3d 20 24 32 22 29 0a  nd owner = $2").
0e50: 09 09 09 2e 62 69 6e 64 28 73 6f 75 72 63 65 5f  ....bind(source_
0e60: 69 64 29 0a 09 09 09 2e 62 69 6e 64 28 6f 77 6e  id).....bind(own
0e70: 65 72 2e 69 6e 74 6f 28 29 29 0a 09 09 09 2e 65  er.into()).....e
0e80: 78 65 63 75 74 65 28 26 6d 75 74 20 2a 73 65 6c  xecute(&mut *sel
0e90: 66 2e 63 6f 6e 6e 29 2e 61 77 61 69 74 3f 2e 72  f.conn).await?.r
0ea0: 6f 77 73 5f 61 66 66 65 63 74 65 64 28 29 20 7b  ows_affected() {
0eb0: 0a 09 09 09 31 20 3d 3e 20 7b 20 4f 6b 28 22 53  ....1 => { Ok("S
0ec0: 6f 75 72 63 65 20 65 6e 61 62 6c 65 64 2e 22 29  ource enabled.")
0ed0: 20 7d 2c 0a 09 09 09 30 20 3d 3e 20 7b 20 4f 6b   },....0 => { Ok
0ee0: 28 22 53 6f 75 72 63 65 20 6e 6f 74 20 66 6f 75  ("Source not fou
0ef0: 6e 64 2e 22 29 20 7d 2c 0a 09 09 09 5f 20 3d 3e  nd.") },...._ =>
0f00: 20 7b 20 62 61 69 6c 21 28 22 44 61 74 61 62 61   { bail!("Databa
0f10: 73 65 20 65 72 72 6f 72 2e 22 29 20 7d 2c 0a 09  se error.") },..
0f20: 09 7d 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79 6e  .}..}...pub asyn
0f30: 63 20 66 6e 20 65 78 69 73 74 73 20 3c 49 3e 20  c fn exists <I> 
0f40: 28 26 6d 75 74 20 73 65 6c 66 2c 20 70 6f 73 74  (&mut self, post
0f50: 5f 75 72 6c 3a 20 26 73 74 72 2c 20 69 64 3a 20  _url: &str, id: 
0f60: 49 29 20 2d 3e 20 52 65 73 75 6c 74 3c 4f 70 74  I) -> Result<Opt
0f70: 69 6f 6e 3c 62 6f 6f 6c 3e 3e 0a 09 77 68 65 72  ion<bool>>..wher
0f80: 65 20 49 3a 20 49 6e 74 6f 3c 69 36 34 3e 20 7b  e I: Into<i64> {
0f90: 0a 09 09 6c 65 74 20 72 6f 77 20 3d 20 73 71 6c  ...let row = sql
0fa0: 78 3a 3a 71 75 65 72 79 28 22 73 65 6c 65 63 74  x::query("select
0fb0: 20 65 78 69 73 74 73 28 73 65 6c 65 63 74 20 74   exists(select t
0fc0: 72 75 65 20 66 72 6f 6d 20 72 73 73 74 67 5f 70  rue from rsstg_p
0fd0: 6f 73 74 20 77 68 65 72 65 20 75 72 6c 20 3d 20  ost where url = 
0fe0: 24 31 20 61 6e 64 20 73 6f 75 72 63 65 5f 69 64  $1 and source_id
0ff0: 20 3d 20 24 32 29 20 61 73 20 65 78 69 73 74 73   = $2) as exists
1000: 3b 22 29 0a 09 09 09 2e 62 69 6e 64 28 70 6f 73  ;").....bind(pos
1010: 74 5f 75 72 6c 29 0a 09 09 09 2e 62 69 6e 64 28  t_url).....bind(
1020: 69 64 2e 69 6e 74 6f 28 29 29 0a 09 09 09 2e 66  id.into()).....f
1030: 65 74 63 68 5f 6f 6e 65 28 26 6d 75 74 20 2a 73  etch_one(&mut *s
1040: 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77 61 69 74 3f  elf.conn).await?
1050: 3b 0a 09 09 6c 65 74 20 65 78 69 73 74 73 3a 20  ;...let exists: 
1060: 4f 70 74 69 6f 6e 3c 62 6f 6f 6c 3e 20 3d 20 72  Option<bool> = r
1070: 6f 77 2e 74 72 79 5f 67 65 74 28 22 65 78 69 73  ow.try_get("exis
1080: 74 73 22 29 3f 3b 0a 09 09 4f 6b 28 65 78 69 73  ts")?;...Ok(exis
1090: 74 73 29 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79  ts)..}...pub asy
10a0: 6e 63 20 66 6e 20 67 65 74 5f 71 75 65 75 65 20  nc fn get_queue 
10b0: 28 26 6d 75 74 20 73 65 6c 66 29 20 2d 3e 20 52  (&mut self) -> R
10c0: 65 73 75 6c 74 3c 56 65 63 3c 51 75 65 75 65 3e  esult<Vec<Queue>
10d0: 3e 20 7b 0a 09 09 6c 65 74 20 62 6c 6f 63 6b 3a  > {...let block:
10e0: 20 56 65 63 3c 51 75 65 75 65 3e 20 3d 20 73 71   Vec<Queue> = sq
10f0: 6c 78 3a 3a 71 75 65 72 79 5f 61 73 28 22 73 65  lx::query_as("se
1100: 6c 65 63 74 20 73 6f 75 72 63 65 5f 69 64 2c 20  lect source_id, 
1110: 6e 65 78 74 5f 66 65 74 63 68 2c 20 6f 77 6e 65  next_fetch, owne
1120: 72 20 66 72 6f 6d 20 72 73 73 74 67 5f 6f 72 64  r from rsstg_ord
1130: 65 72 20 6e 61 74 75 72 61 6c 20 6c 65 66 74 20  er natural left 
1140: 6a 6f 69 6e 20 72 73 73 74 67 5f 73 6f 75 72 63  join rsstg_sourc
1150: 65 20 77 68 65 72 65 20 6e 65 78 74 5f 66 65 74  e where next_fet
1160: 63 68 20 3c 20 6e 6f 77 28 29 20 2b 20 69 6e 74  ch < now() + int
1170: 65 72 76 61 6c 20 27 31 20 6d 69 6e 75 74 65 27  erval '1 minute'
1180: 3b 22 29 0a 09 09 09 2e 66 65 74 63 68 5f 61 6c  ;").....fetch_al
1190: 6c 28 26 6d 75 74 20 2a 73 65 6c 66 2e 63 6f 6e  l(&mut *self.con
11a0: 6e 29 2e 61 77 61 69 74 3f 3b 0a 09 09 4f 6b 28  n).await?;...Ok(
11b0: 62 6c 6f 63 6b 29 0a 09 7d 0a 0a 09 70 75 62 20  block)..}...pub 
11c0: 61 73 79 6e 63 20 66 6e 20 67 65 74 5f 6c 69 73  async fn get_lis
11d0: 74 20 3c 49 3e 20 28 26 6d 75 74 20 73 65 6c 66  t <I> (&mut self
11e0: 2c 20 6f 77 6e 65 72 3a 20 49 29 20 2d 3e 20 52  , owner: I) -> R
11f0: 65 73 75 6c 74 3c 56 65 63 3c 4c 69 73 74 3e 3e  esult<Vec<List>>
1200: 0a 09 77 68 65 72 65 20 49 3a 20 49 6e 74 6f 3c  ..where I: Into<
1210: 69 36 34 3e 20 7b 0a 09 09 6c 65 74 20 73 6f 75  i64> {...let sou
1220: 72 63 65 3a 20 56 65 63 3c 4c 69 73 74 3e 20 3d  rce: Vec<List> =
1230: 20 73 71 6c 78 3a 3a 71 75 65 72 79 5f 61 73 28   sqlx::query_as(
1240: 22 73 65 6c 65 63 74 20 73 6f 75 72 63 65 5f 69  "select source_i
1250: 64 2c 20 63 68 61 6e 6e 65 6c 2c 20 65 6e 61 62  d, channel, enab
1260: 6c 65 64 2c 20 75 72 6c 2c 20 69 76 5f 68 61 73  led, url, iv_has
1270: 68 2c 20 75 72 6c 5f 72 65 20 66 72 6f 6d 20 72  h, url_re from r
1280: 73 73 74 67 5f 73 6f 75 72 63 65 20 77 68 65 72  sstg_source wher
1290: 65 20 6f 77 6e 65 72 20 3d 20 24 31 20 6f 72 64  e owner = $1 ord
12a0: 65 72 20 62 79 20 73 6f 75 72 63 65 5f 69 64 22  er by source_id"
12b0: 29 0a 09 09 09 2e 62 69 6e 64 28 6f 77 6e 65 72  ).....bind(owner
12c0: 2e 69 6e 74 6f 28 29 29 0a 09 09 09 2e 66 65 74  .into()).....fet
12d0: 63 68 5f 61 6c 6c 28 26 6d 75 74 20 2a 73 65 6c  ch_all(&mut *sel
12e0: 66 2e 63 6f 6e 6e 29 2e 61 77 61 69 74 3f 3b 0a  f.conn).await?;.
12f0: 09 09 4f 6b 28 73 6f 75 72 63 65 29 0a 09 7d 0a  ..Ok(source)..}.
1300: 0a 09 70 75 62 20 61 73 79 6e 63 20 66 6e 20 67  ..pub async fn g
1310: 65 74 5f 6f 6e 65 20 3c 49 3e 20 28 26 6d 75 74  et_one <I> (&mut
1320: 20 73 65 6c 66 2c 20 6f 77 6e 65 72 3a 20 49 2c   self, owner: I,
1330: 20 69 64 3a 20 69 33 32 29 20 2d 3e 20 52 65 73   id: i32) -> Res
1340: 75 6c 74 3c 4f 70 74 69 6f 6e 3c 4c 69 73 74 3e  ult<Option<List>
1350: 3e 0a 09 77 68 65 72 65 20 49 3a 20 49 6e 74 6f  >..where I: Into
1360: 3c 69 36 34 3e 20 7b 0a 09 09 6c 65 74 20 73 6f  <i64> {...let so
1370: 75 72 63 65 3a 20 4f 70 74 69 6f 6e 3c 4c 69 73  urce: Option<Lis
1380: 74 3e 20 3d 20 73 71 6c 78 3a 3a 71 75 65 72 79  t> = sqlx::query
1390: 5f 61 73 28 22 73 65 6c 65 63 74 20 73 6f 75 72  _as("select sour
13a0: 63 65 5f 69 64 2c 20 63 68 61 6e 6e 65 6c 2c 20  ce_id, channel, 
13b0: 65 6e 61 62 6c 65 64 2c 20 75 72 6c 2c 20 69 76  enabled, url, iv
13c0: 5f 68 61 73 68 2c 20 75 72 6c 5f 72 65 20 66 72  _hash, url_re fr
13d0: 6f 6d 20 72 73 73 74 67 5f 73 6f 75 72 63 65 20  om rsstg_source 
13e0: 77 68 65 72 65 20 6f 77 6e 65 72 20 3d 20 24 31  where owner = $1
13f0: 20 61 6e 64 20 73 6f 75 72 63 65 5f 69 64 20 3d   and source_id =
1400: 20 24 32 22 29 0a 09 09 09 2e 62 69 6e 64 28 6f   $2").....bind(o
1410: 77 6e 65 72 2e 69 6e 74 6f 28 29 29 0a 09 09 09  wner.into())....
1420: 2e 62 69 6e 64 28 69 64 29 0a 09 09 09 2e 66 65  .bind(id).....fe
1430: 74 63 68 5f 6f 70 74 69 6f 6e 61 6c 28 26 6d 75  tch_optional(&mu
1440: 74 20 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77  t *self.conn).aw
1450: 61 69 74 3f 3b 0a 09 09 4f 6b 28 73 6f 75 72 63  ait?;...Ok(sourc
1460: 65 29 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79 6e  e)..}...pub asyn
1470: 63 20 66 6e 20 67 65 74 5f 73 6f 75 72 63 65 20  c fn get_source 
1480: 3c 49 3e 20 28 26 6d 75 74 20 73 65 6c 66 2c 20  <I> (&mut self, 
1490: 69 64 3a 20 69 33 32 2c 20 6f 77 6e 65 72 3a 20  id: i32, owner: 
14a0: 49 29 20 2d 3e 20 52 65 73 75 6c 74 3c 53 6f 75  I) -> Result<Sou
14b0: 72 63 65 3e 0a 09 77 68 65 72 65 20 49 3a 20 49  rce>..where I: I
14c0: 6e 74 6f 3c 69 36 34 3e 20 7b 0a 09 09 6c 65 74  nto<i64> {...let
14d0: 20 73 6f 75 72 63 65 3a 20 53 6f 75 72 63 65 20   source: Source 
14e0: 3d 20 73 71 6c 78 3a 3a 71 75 65 72 79 5f 61 73  = sqlx::query_as
14f0: 28 22 73 65 6c 65 63 74 20 63 68 61 6e 6e 65 6c  ("select channel
1500: 5f 69 64 2c 20 75 72 6c 2c 20 69 76 5f 68 61 73  _id, url, iv_has
1510: 68 2c 20 6f 77 6e 65 72 2c 20 75 72 6c 5f 72 65  h, owner, url_re
1520: 20 66 72 6f 6d 20 72 73 73 74 67 5f 73 6f 75 72   from rsstg_sour
1530: 63 65 20 77 68 65 72 65 20 73 6f 75 72 63 65 5f  ce where source_
1540: 69 64 20 3d 20 24 31 20 61 6e 64 20 6f 77 6e 65  id = $1 and owne
1550: 72 20 3d 20 24 32 22 29 0a 09 09 09 2e 62 69 6e  r = $2").....bin
1560: 64 28 69 64 29 0a 09 09 09 2e 62 69 6e 64 28 6f  d(id).....bind(o
1570: 77 6e 65 72 2e 69 6e 74 6f 28 29 29 0a 09 09 09  wner.into())....
1580: 2e 66 65 74 63 68 5f 6f 6e 65 28 26 6d 75 74 20  .fetch_one(&mut 
1590: 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77 61 69  *self.conn).awai
15a0: 74 3f 3b 0a 09 09 4f 6b 28 73 6f 75 72 63 65 29  t?;...Ok(source)
15b0: 0a 09 7d 0a 0a 09 70 75 62 20 61 73 79 6e 63 20  ..}...pub async 
15c0: 66 6e 20 73 65 74 5f 73 63 72 61 70 65 20 3c 49  fn set_scrape <I
15d0: 3e 20 28 26 6d 75 74 20 73 65 6c 66 2c 20 69 64  > (&mut self, id
15e0: 3a 20 49 29 20 2d 3e 20 52 65 73 75 6c 74 3c 28  : I) -> Result<(
15f0: 29 3e 0a 09 77 68 65 72 65 20 49 3a 20 49 6e 74  )>..where I: Int
1600: 6f 3c 69 36 34 3e 20 7b 0a 09 09 73 71 6c 78 3a  o<i64> {...sqlx:
1610: 3a 71 75 65 72 79 28 22 75 70 64 61 74 65 20 72  :query("update r
1620: 73 73 74 67 5f 73 6f 75 72 63 65 20 73 65 74 20  sstg_source set 
1630: 6c 61 73 74 5f 73 63 72 61 70 65 20 3d 20 6e 6f  last_scrape = no
1640: 77 28 29 20 77 68 65 72 65 20 73 6f 75 72 63 65  w() where source
1650: 5f 69 64 20 3d 20 24 31 3b 22 29 0a 09 09 09 2e  _id = $1;").....
1660: 62 69 6e 64 28 69 64 2e 69 6e 74 6f 28 29 29 0a  bind(id.into()).
1670: 09 09 09 2e 65 78 65 63 75 74 65 28 26 6d 75 74  ....execute(&mut
1680: 20 2a 73 65 6c 66 2e 63 6f 6e 6e 29 2e 61 77 61   *self.conn).awa
1690: 69 74 3f 3b 0a 09 09 4f 6b 28 28 29 29 0a 09 7d  it?;...Ok(())..}
16a0: 0a 0a 09 70 75 62 20 61 73 79 6e 63 20 66 6e 20  ...pub async fn 
16b0: 75 70 64 61 74 65 20 3c 49 3e 20 28 26 6d 75 74  update <I> (&mut
16c0: 20 73 65 6c 66 2c 20 75 70 64 61 74 65 3a 20 4f   self, update: O
16d0: 70 74 69 6f 6e 3c 69 33 32 3e 2c 20 63 68 61 6e  ption<i32>, chan
16e0: 6e 65 6c 3a 20 26 73 74 72 2c 20 63 68 61 6e 6e  nel: &str, chann
16f0: 65 6c 5f 69 64 3a 20 69 36 34 2c 20 75 72 6c 3a  el_id: i64, url:
1700: 20 26 73 74 72 2c 20 69 76 5f 68 61 73 68 3a 20   &str, iv_hash: 
1710: 4f 70 74 69 6f 6e 3c 26 73 74 72 3e 2c 20 75 72  Option<&str>, ur
1720: 6c 5f 72 65 3a 20 4f 70 74 69 6f 6e 3c 26 73 74  l_re: Option<&st
1730: 72 3e 2c 20 6f 77 6e 65 72 3a 20 49 29 20 2d 3e  r>, owner: I) ->
1740: 20 52 65 73 75 6c 74 3c 26 73 74 72 3e 0a 09 77   Result<&str>..w
1750: 68 65 72 65 20 49 3a 20 49 6e 74 6f 3c 69 36 34  here I: Into<i64
1760: 3e 20 7b 0a 09 09 6d 61 74 63 68 20 6d 61 74 63  > {...match matc
1770: 68 20 75 70 64 61 74 65 20 7b 0a 09 09 09 09 53  h update {.....S
1780: 6f 6d 65 28 69 64 29 20 3d 3e 20 7b 0a 09 09 09  ome(id) => {....
1790: 09 09 73 71 6c 78 3a 3a 71 75 65 72 79 28 22 75  ..sqlx::query("u
17a0: 70 64 61 74 65 20 72 73 73 74 67 5f 73 6f 75 72  pdate rsstg_sour
17b0: 63 65 20 73 65 74 20 63 68 61 6e 6e 65 6c 5f 69  ce set channel_i
17c0: 64 20 3d 20 24 32 2c 20 75 72 6c 20 3d 20 24 33  d = $2, url = $3
17d0: 2c 20 69 76 5f 68 61 73 68 20 3d 20 24 34 2c 20  , iv_hash = $4, 
17e0: 6f 77 6e 65 72 20 3d 20 24 35 2c 20 63 68 61 6e  owner = $5, chan
17f0: 6e 65 6c 20 3d 20 24 36 2c 20 75 72 6c 5f 72 65  nel = $6, url_re
1800: 20 3d 20 24 37 20 77 68 65 72 65 20 73 6f 75 72   = $7 where sour
1810: 63 65 5f 69 64 20 3d 20 24 31 22 29 0a 09 09 09  ce_id = $1")....
1820: 09 09 09 2e 62 69 6e 64 28 69 64 29 0a 09 09 09  ....bind(id)....
1830: 09 7d 2c 0a 09 09 09 09 4e 6f 6e 65 20 3d 3e 20  .},.....None => 
1840: 7b 0a 09 09 09 09 09 73 71 6c 78 3a 3a 71 75 65  {......sqlx::que
1850: 72 79 28 22 69 6e 73 65 72 74 20 69 6e 74 6f 20  ry("insert into 
1860: 72 73 73 74 67 5f 73 6f 75 72 63 65 20 28 63 68  rsstg_source (ch
1870: 61 6e 6e 65 6c 5f 69 64 2c 20 75 72 6c 2c 20 69  annel_id, url, i
1880: 76 5f 68 61 73 68 2c 20 6f 77 6e 65 72 2c 20 63  v_hash, owner, c
1890: 68 61 6e 6e 65 6c 2c 20 75 72 6c 5f 72 65 29 20  hannel, url_re) 
18a0: 76 61 6c 75 65 73 20 28 24 31 2c 20 24 32 2c 20  values ($1, $2, 
18b0: 24 33 2c 20 24 34 2c 20 24 35 2c 20 24 36 29 22  $3, $4, $5, $6)"
18c0: 29 0a 09 09 09 09 7d 2c 0a 09 09 09 7d 0a 09 09  ).....},....}...
18d0: 09 09 2e 62 69 6e 64 28 63 68 61 6e 6e 65 6c 5f  ...bind(channel_
18e0: 69 64 29 0a 09 09 09 09 2e 62 69 6e 64 28 75 72  id)......bind(ur
18f0: 6c 29 0a 09 09 09 09 2e 62 69 6e 64 28 69 76 5f  l)......bind(iv_
1900: 68 61 73 68 29 0a 09 09 09 09 2e 62 69 6e 64 28  hash)......bind(
1910: 6f 77 6e 65 72 2e 69 6e 74 6f 28 29 29 0a 09 09  owner.into())...
1920: 09 09 2e 62 69 6e 64 28 63 68 61 6e 6e 65 6c 29  ...bind(channel)
1930: 0a 09 09 09 09 2e 62 69 6e 64 28 75 72 6c 5f 72  ......bind(url_r
1940: 65 29 0a 09 09 09 09 2e 65 78 65 63 75 74 65 28  e)......execute(
1950: 26 6d 75 74 20 2a 73 65 6c 66 2e 63 6f 6e 6e 29  &mut *self.conn)
1960: 2e 61 77 61 69 74 0a 09 09 09 7b 0a 09 09 09 4f  .await....{....O
1970: 6b 28 5f 29 20 3d 3e 20 4f 6b 28 6d 61 74 63 68  k(_) => Ok(match
1980: 20 75 70 64 61 74 65 20 7b 0a 09 09 09 09 53 6f   update {.....So
1990: 6d 65 28 5f 29 20 3d 3e 20 22 43 68 61 6e 6e 65  me(_) => "Channe
19a0: 6c 20 75 70 64 61 74 65 64 2e 22 2c 0a 09 09 09  l updated.",....
19b0: 09 4e 6f 6e 65 20 3d 3e 20 22 43 68 61 6e 6e 65  .None => "Channe
19c0: 6c 20 61 64 64 65 64 2e 22 2c 0a 09 09 09 7d 29  l added.",....})
19d0: 2c 0a 09 09 09 45 72 72 28 73 71 6c 78 3a 3a 45  ,....Err(sqlx::E
19e0: 72 72 6f 72 3a 3a 44 61 74 61 62 61 73 65 28 65  rror::Database(e
19f0: 72 72 29 29 20 3d 3e 20 7b 0a 09 09 09 09 6d 61  rr)) => {.....ma
1a00: 74 63 68 20 65 72 72 2e 64 6f 77 6e 63 61 73 74  tch err.downcast
1a10: 3a 3a 3c 73 71 6c 78 3a 3a 70 6f 73 74 67 72 65  ::<sqlx::postgre
1a20: 73 3a 3a 50 67 44 61 74 61 62 61 73 65 45 72 72  s::PgDatabaseErr
1a30: 6f 72 3e 28 29 2e 72 6f 75 74 69 6e 65 28 29 20  or>().routine() 
1a40: 7b 0a 09 09 09 09 09 53 6f 6d 65 28 22 5f 62 74  {......Some("_bt
1a50: 5f 63 68 65 63 6b 5f 75 6e 69 71 75 65 22 2c 20  _check_unique", 
1a60: 29 20 3d 3e 20 7b 0a 09 09 09 09 09 09 4f 6b 28  ) => {.......Ok(
1a70: 22 44 75 70 6c 69 63 61 74 65 20 6b 65 79 2e 22  "Duplicate key."
1a80: 29 0a 09 09 09 09 09 7d 2c 0a 09 09 09 09 09 53  )......},......S
1a90: 6f 6d 65 28 5f 29 20 3d 3e 20 7b 0a 09 09 09 09  ome(_) => {.....
1aa0: 09 09 4f 6b 28 22 44 61 74 61 62 61 73 65 20 65  ..Ok("Database e
1ab0: 72 72 6f 72 2e 22 29 0a 09 09 09 09 09 7d 2c 0a  rror.")......},.
1ac0: 09 09 09 09 09 4e 6f 6e 65 20 3d 3e 20 7b 0a 09  .....None => {..
1ad0: 09 09 09 09 09 4f 6b 28 22 4e 6f 20 64 61 74 61  .....Ok("No data
1ae0: 62 61 73 65 20 65 72 72 6f 72 20 65 78 74 72 61  base error extra
1af0: 63 74 65 64 2e 22 29 0a 09 09 09 09 09 7d 2c 0a  cted.")......},.
1b00: 09 09 09 09 7d 0a 09 09 09 7d 2c 0a 09 09 09 45  ....}....},....E
1b10: 72 72 28 65 72 72 29 20 3d 3e 20 7b 0a 09 09 09  rr(err) => {....
1b20: 09 62 61 69 6c 21 28 22 53 6f 72 72 79 2c 20 75  .bail!("Sorry, u
1b30: 6e 6b 6e 6f 77 6e 20 65 72 72 6f 72 3a 5c 6e 7b  nknown error:\n{
1b40: 65 72 72 3a 23 3f 7d 5c 6e 22 29 3b 0a 09 09 09  err:#?}\n");....
1b50: 7d 2c 0a 09 09 7d 0a 09 7d 0a 7d 0a              },...}..}.}.