ergol_cli/
db.rs

1//! This module contains all the functions to help deal with the database.
2
3use tokio_postgres::{Client, Error};
4
5pub async fn current_migration(db: &Client) -> Result<Option<i32>, Error> {
6    // If there is a problem with the db, this will launch an error.
7    db.query("SELECT 1;", &[]).await?;
8
9    // Which means that if this fail, it's because the ergol table doesn't exist.
10    Ok(db
11        .query("SELECT * FROM ergol;", &[])
12        .await
13        .ok()
14        .map(|x| x[0].get(0)))
15}
16
17pub async fn create_current_migration(db: &Client) -> Result<(), Error> {
18    let table = ergol_core::Table::current_migration().create_table();
19    db.query(&table as &str, &[]).await?;
20    db.query("INSERT INTO ergol VALUES(-1)", &[]).await?;
21    Ok(())
22}
23
24pub async fn set_migration(value: i32, db: &Client) -> Result<(), Error> {
25    db.query("UPDATE ergol SET migration = $1;", &[&value])
26        .await?;
27    Ok(())
28}
29
30pub async fn clear(db: &Client) -> Result<(), Error> {
31    // Clear tables
32    db.query(
33        r#"
34        DO $$ DECLARE
35          r RECORD;
36        BEGIN
37          FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
38            EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
39          END LOOP;
40        END $$;
41    "#,
42        &[],
43    )
44    .await?;
45
46    // Clear types
47    db.query(
48        r#"
49        DO $$ DECLARE
50            r RECORD;
51        BEGIN
52            FOR r IN (
53                SELECT      n.nspname as schema, t.typname as type
54                FROM        pg_type t
55                LEFT JOIN   pg_catalog.pg_namespace n ON n.oid = t.typnamespace
56                WHERE       (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))
57                AND         NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
58                AND         n.nspname NOT IN ('pg_catalog', 'information_schema')
59            ) LOOP
60                EXECUTE 'DROP TYPE IF EXISTS ' || quote_ident(r.type) || ' CASCADE';
61            END LOOP;
62        END $$;
63    "#,
64        &[]
65    ).await?;
66
67    Ok(())
68}