tea_orm/queries/
create_database_from_template.rs

1use crate::queries::is_alphanumeric_underscore_hyphen;
2use anyhow::anyhow;
3use anyhow::Context;
4use anyhow::Result;
5use sea_orm::query::ConnectionTrait;
6use sea_orm::query::Statement;
7use sea_orm::DatabaseConnection;
8use sea_orm::DbBackend;
9use std::fmt::Display;
10
11/// Runs a query which will create a new database with the given name.
12pub async fn query_create_database_from_template<S, T>(
13    db_connection: &DatabaseConnection,
14    name: &S,
15    template_name: &T,
16) -> Result<()>
17where
18    S: Display,
19    T: Display,
20{
21    let db_backend = db_connection.get_database_backend();
22    let db_name = name.to_string();
23    let db_template_name = template_name.to_string();
24    let create_db_statement =
25        create_database_statement_from_template(db_backend, &db_name, &db_template_name)?;
26
27    db_connection
28        .execute(create_db_statement)
29        .await
30        .with_context(|| format!("Trying to create new database with name '{}'", db_name))?;
31
32    Ok(())
33}
34
35fn create_database_statement_from_template(
36    db_backend: DbBackend,
37    db_name: &str,
38    db_template_name: &str,
39) -> Result<Statement> {
40    if !is_alphanumeric_underscore_hyphen(db_name) {
41        return Err(anyhow!(
42            "Given database name is empty or contains non-alphanumeric characters '{}'",
43            db_name
44        ));
45    }
46
47    let statement = match db_backend {
48        DbBackend::Postgres => {
49            let raw_sql = format!(r#"CREATE DATABASE "{db_name}" TEMPLATE "{db_template_name}""#);
50            let statement = Statement::from_string(db_backend, raw_sql);
51
52            statement
53        }
54        _ => {
55            unimplemented!("Unsupported db backend used")
56        }
57    };
58
59    Ok(statement)
60}
61
62#[cfg(test)]
63mod query_create_database_from_template {
64    use crate::new_database_connection;
65    use crate::queries::query_create_random_database;
66    use crate::queries::query_create_random_database_from_template;
67
68    const POSTGRES_LOCAL_DB_URL: &'static str = &"postgres://user:password@localhost:5432/tea-orm";
69
70    #[tokio::test]
71    async fn it_should_clone_db() {
72        let db_connection = new_database_connection(POSTGRES_LOCAL_DB_URL.to_string())
73            .await
74            .unwrap();
75        let db_name = query_create_random_database(&db_connection).await.unwrap();
76        let result = query_create_random_database_from_template(&db_connection, &db_name).await;
77
78        assert!(result.is_ok());
79    }
80}