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
58
59
60
61
use crate::error::Error;
use crate::migrate::{MigrateError, Migration};
use futures_core::future::BoxFuture;
use std::time::Duration;

pub trait MigrateDatabase {
    // create database in uri
    // uses a maintenance database depending on driver
    fn create_database(uri: &str) -> BoxFuture<'_, Result<(), Error>>;

    // check if the database in uri exists
    // uses a maintenance database depending on driver
    fn database_exists(uri: &str) -> BoxFuture<'_, Result<bool, Error>>;

    // drop database in uri
    // uses a maintenance database depending on driver
    fn drop_database(uri: &str) -> BoxFuture<'_, Result<(), Error>>;
}

// 'e = Executor
pub trait Migrate {
    // ensure migrations table exists
    // will create or migrate it if needed
    fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>>;

    // Return the current version and if the database is "dirty".
    // "dirty" means there is a partially applied migration that failed.
    fn version(&mut self) -> BoxFuture<'_, Result<Option<(i64, bool)>, MigrateError>>;

    // Should acquire a database lock so that only one migration process
    // can run at a time. [`Migrate`] will call this function before applying
    // any migrations.
    fn lock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>>;

    // Should release the lock. [`Migrate`] will call this function after all
    // migrations have been run.
    fn unlock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>>;

    // validate the migration
    // checks that it does exist on the database and that the checksum matches
    fn validate<'e: 'm, 'm>(
        &'e mut self,
        migration: &'m Migration,
    ) -> BoxFuture<'m, Result<(), MigrateError>>;

    // run SQL from migration in a DDL transaction
    // insert new row to [_migrations] table on completion (success or failure)
    // returns the time taking to run the migration SQL
    fn apply<'e: 'm, 'm>(
        &'e mut self,
        migration: &'m Migration,
    ) -> BoxFuture<'m, Result<Duration, MigrateError>>;

    // run a revert SQL from migration in a DDL transaction
    // deletes the row in [_migrations] table with specified migration version on completion (success or failure)
    // returns the time taking to run the migration SQL
    fn revert<'e: 'm, 'm>(
        &'e mut self,
        migration: &'m Migration,
    ) -> BoxFuture<'m, Result<Duration, MigrateError>>;
}