1use async_trait::async_trait;
2use sqlx::postgres::PgQueryResult;
3use sqlx::{Database, Error, Pool, Postgres, Transaction};
4
5use crate::{statement, Aggregate};
6
7#[async_trait]
9pub trait MigrationsHandler<D>
10where
11 D: Database,
12{
13 async fn run<A>(pool: &Pool<D>) -> Result<(), Error>
14 where
15 A: Aggregate;
16}
17
18pub struct Migrations;
19
20#[async_trait]
21impl MigrationsHandler<Postgres> for Migrations {
22 async fn run<A>(pool: &Pool<Postgres>) -> Result<(), Error>
23 where
24 A: Aggregate,
25 {
26 let mut transaction: Transaction<Postgres> = pool.begin().await?;
27
28 let migrations: Vec<String> = vec![
29 statement!("postgres/migrations/01_create_table.sql", A),
30 statement!("postgres/migrations/02_create_index.sql", A),
31 statement!("postgres/migrations/03_create_unique_constraint.sql", A),
32 statement!("postgres/migrations/04_add_version.sql", A),
33 ];
34
35 for migration in migrations {
36 let _: PgQueryResult = sqlx::query(migration.as_str()).execute(&mut *transaction).await?;
37 }
38
39 transaction.commit().await
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use sqlx::{Pool, Postgres};
46
47 use crate::sql::migrations::{Migrations, MigrationsHandler};
48 use crate::Aggregate;
49
50 #[sqlx::test]
51 async fn can_read_postgres_migrations(pool: Pool<Postgres>) {
52 let result = Migrations::run::<TestAggregate>(&pool).await;
53 dbg!(&result);
54 assert!(result.is_ok());
55 }
56
57 #[derive(Debug, thiserror::Error)]
58 pub enum Error {}
59
60 pub struct TestAggregate;
61
62 #[derive(serde::Serialize, serde::Deserialize)]
63 pub struct TestEvent;
64
65 #[cfg(feature = "upcasting")]
66 impl crate::event::Upcaster for TestEvent {}
67
68 impl Aggregate for TestAggregate {
69 const NAME: &'static str = "test";
70 type State = ();
71 type Command = ();
72 type Event = TestEvent;
73 type Error = Error;
74
75 fn handle_command(_state: &Self::State, _command: Self::Command) -> Result<Vec<Self::Event>, Self::Error> {
76 Ok(vec![])
77 }
78
79 fn apply_event(_state: Self::State, _payload: Self::Event) -> Self::State {}
80 }
81}