use crate::{database::Database, writers::write_to_file};
use color_eyre::eyre::Result;
use futures_util::future::FutureExt;
use sqlparser::dialect::SQLiteDialect;
use sqlx::{mysql::MySqlConnectOptions, MySqlPool};
use std::str::FromStr;
use tokio_postgres::{Config, NoTls};
pub fn write_to_sql(file_name: &String, sql: &str) -> Result<(), std::io::Error> {
let _ = sqlparser::parser::Parser::parse_sql(&SQLiteDialect {}, sql).unwrap();
let mut template = String::new();
template.push_str(&sql.to_string());
write_to_file(file_name, template.as_bytes())
}
pub async fn create_database_if_not_exists(
admin_database_url: &str,
database: Database,
) -> Result<(), Box<dyn std::error::Error>> {
match database.database_type {
crate::database::DatabaseType::Postgres => {
let config = Config::from_str(admin_database_url).unwrap();
let (client, connection) = config.connect(NoTls).await.unwrap();
let connection_task = connection.map(|r| {
if let Err(e) = r {
eprintln!("Connection error: {}", e);
}
});
tokio::spawn(connection_task);
let row = client
.query_opt(
"SELECT 1 FROM pg_database WHERE datname = $1",
&[&database.name],
)
.await
.unwrap();
if row.is_none() {
client
.batch_execute(&format!("CREATE DATABASE \"{}\"", &database.name))
.await
.unwrap();
}
}
crate::database::DatabaseType::Mysql => {
let mut options = MySqlConnectOptions::from_str(admin_database_url).unwrap();
options = options.database("mysql");
let pool = MySqlPool::connect_with(options).await.unwrap();
let row: Option<(String,)> = sqlx::query_as(
"SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?",
)
.bind(&database.name)
.fetch_optional(&pool)
.await
.unwrap();
if row.is_none() {
sqlx::query(&format!("CREATE DATABASE {}", &database.name))
.execute(&pool)
.await
.unwrap();
}
}
crate::database::DatabaseType::Sqlite => todo!(),
crate::database::DatabaseType::Mongo => todo!(),
}
Ok(())
}