1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use postgres::{GenericClient, Row};

use crate::migration_data::migrations::Migration;

pub type BinaryHash = [u8; 32];

pub fn slice_to_hash(slice: &[u8]) -> BinaryHash {
  let mut buf = [0; 32];
  buf.copy_from_slice(slice);
  buf
}

pub struct TriedMigration {
  pub id: String,
  /// hex encoded hash
  pub hash: String,
  pub tried_at: time::OffsetDateTime
}

impl TriedMigration {
  pub fn from_row(row: Row) -> Self {
    Self {
      id: row.get(0),
      hash: row.get(1),
      tried_at: row.get(2),
    }
  }

  pub fn create(client: &mut impl GenericClient, m: &Migration) -> anyhow::Result<TriedMigration> {
    let hash = m.migrate_hash()?;
    let row = client.query_one("INSERT INTO salmo_tried_migrations (id, hash) VALUES ($1, $2) RETURNING id, hash, tried_at", &[
      &m.id, &hash
    ])?;
    Ok(TriedMigration::from_row(row))
  }

  pub fn delete(client: &mut impl GenericClient, m: &Migration) -> anyhow::Result<Option<TriedMigration>> {
    let r = client.query_opt("DELETE FROM salmo_tried_migrations WHERE id = $1 RETURNING id, hash, tried_at", &[
      &m.id
    ])?;
    Ok(r.map(TriedMigration::from_row))
  }

  pub fn get_all(client: &mut impl GenericClient) -> anyhow::Result<Vec<TriedMigration>> {
    let tries = client.query("SELECT id, hash, tried_at FROM salmo_tried_migrations", &[])?
      .into_iter()
      .map(Self::from_row)
    .collect();
    Ok(tries)
  }

  pub fn get(client: &mut impl GenericClient, id: &str) -> anyhow::Result<Option<TriedMigration>> {
    Ok(client.query_opt("SELECT id, hash, tried_at FROM salmo_tried_migrations WHERE id = $1", &[&id])?.map(TriedMigration::from_row))
  }


}