aboutsummaryrefslogtreecommitdiff
path: root/src/db/mod.rs
blob: 1a60ce38ab6fad90185956dee2940acb03f403b3 (plain) (blame)
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
use miette::Diagnostic;
use thiserror::Error;

pub struct Migration {
    pub filename: String,
    pub directory: String,
    pub script_contents: String,
}

const DB_MIGRATION_DIR: &str = "./src/db/";

/// To prevent accidental error coersion in other modules, std::io::Error gets cast as Migration Error here
#[derive(Debug, Diagnostic, Error)]
pub enum MigrationError {
    #[error("IO error")]
    IOMigrationError(#[from] std::io::Error),
}

type Result<T> = std::result::Result<T, MigrationError>;

/// Reads the filesystem for sql files in the DB migration directory
fn get_script_filenames() -> Result<Vec<String>> {
    let results = std::fs::read_dir(DB_MIGRATION_DIR)?;

    Ok(results
        .flat_map(|entry| entry.unwrap().file_name().into_string())
        .filter(|s| s.ends_with(".sql"))
        .collect())
}

/// Gets SQL files from the DB migration directory to provide instructions for setting up the database
pub fn get_migration_scripts() -> Result<Vec<Migration>> {
    let files = get_script_filenames()?;
    let mut migrations = vec![];

    for file in files {
        let filename = String::from(DB_MIGRATION_DIR) + &file;
        tracing::event!(
            tracing::Level::TRACE,
            filename = filename,
            "Found migration script."
        );

        let contents = std::fs::read_to_string(filename)?;

        migrations.push(Migration {
            filename: file,
            directory: DB_MIGRATION_DIR.into(),
            script_contents: contents,
        });
    }

    Ok(migrations)
}