tern_core/executor/sqlx_backend/
postgres.rs

1//! [`Executor`] for [`sqlx::PgPool`][pg-pool].
2//!
3//! [`Executor`]: crate::migration::Executor
4//! [pg-pool]: https://docs.rs/sqlx/0.8.3/sqlx/type.PgPool.html
5use sqlx::Postgres;
6
7use super::pool::SqlxExecutor;
8use crate::migration::{AppliedMigration, Query, QueryRepository};
9
10/// Specialization of `SqlxExecutor` to `sqlx::PgPool`.
11pub type SqlxPgExecutor = SqlxExecutor<Postgres, SqlxPgQueryRepo>;
12
13/// The schema history table queries for postgres.
14#[derive(Debug, Clone)]
15pub struct SqlxPgQueryRepo;
16
17impl QueryRepository for SqlxPgQueryRepo {
18    fn create_history_if_not_exists_query(history_table: &str) -> Query {
19        let sql = format!(
20            "
21CREATE TABLE IF NOT EXISTS {history_table}(
22  version bigint PRIMARY KEY,
23  description text NOT NULL,
24  content text NOT NULL,
25  duration_ms bigint NOT NULL,
26  applied_at timestamptz NOT NULL DEFAULT now()
27);
28"
29        );
30
31        Query::new(sql)
32    }
33
34    fn drop_history_query(history_table: &str) -> Query {
35        let sql = format!("DROP TABLE IF EXISTS {history_table};");
36
37        Query::new(sql)
38    }
39
40    fn insert_into_history_query(history_table: &str, _: &AppliedMigration) -> Query {
41        // With `sqlx` we're not going to use the `AppliedMigration`, the values
42        // will get in the query by `bind`ing them.
43        let sql = format!(
44            "
45INSERT INTO {history_table}(version, description, content, duration_ms, applied_at)
46  VALUES ($1, $2, $3, $4, $5);
47"
48        );
49
50        Query::new(sql)
51    }
52
53    fn select_star_from_history_query(history_table: &str) -> Query {
54        let sql = format!(
55            "
56SELECT
57  version,
58  description,
59  content,
60  duration_ms,
61  applied_at
62FROM
63  {history_table}
64ORDER BY
65  version;
66"
67        );
68
69        Query::new(sql)
70    }
71
72    fn upsert_history_query(history_table: &str, _: &AppliedMigration) -> Query {
73        let sql = format!(
74            "
75INSERT INTO {history_table}(version, description, content, duration_ms, applied_at)
76  VALUES ($1, $2, $3, $4, $5)
77  ON CONFLICT (version) DO UPDATE
78  SET
79    description = excluded.description,
80    content = excluded.content,
81    duration_ms = excluded.duration_ms,
82    applied_at = excluded.applied_at;
83"
84        );
85
86        Query::new(sql)
87    }
88}