Skip to content

Commit

Permalink
added sqlite
Browse files Browse the repository at this point in the history
  • Loading branch information
emilpriver committed Dec 21, 2023
1 parent b21c26f commit 544ec6c
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ clap = { version = "4.4.11", features = ["env", "string", "derive", "cargo"] }
futures = "0.3.29"
libsql-client = { version = "0.33.2", features = ["futures-util", "http"] }
log = { version = "0.4.20", features = ["max_level_debug", "serde"] }
mockall = "0.12.0"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
serial_test = "2.0.0"
simplelog = "0.12.1"
sqlx = { version = "0.7.3", features = ["runtime-tokio", "chrono", "postgres", "mysql", "sqlite", "time"] }
tempdir = "0.3.7"
tokio = { version = "1.35.0", features = ["full"] }

[dev-dependencies]
mockall = "0.12.0"
tempfile = "3.8.1"
tempdir = "0.3.7"
1 change: 1 addition & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl Database {
Database::MariaDB => "mariadb",
Database::MySQL => "mysql",
Database::SQLite => "sqlite",
_ => panic!("Unknown database driver"),
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/database_drivers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::pin::Pin;
pub mod libsql;
pub mod mysql;
pub mod postgres;
pub mod sqlite;

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct SchemaMigration {
Expand Down Expand Up @@ -54,7 +55,10 @@ pub async fn new(
let driver = mysql::MySQLDriver::new(db_url).await?;
Ok(Box::new(driver))
}
config::Database::SQLite => {
let driver = sqlite::SqliteDriver::new(db_url).await?;
Ok(Box::new(driver))
}
config::Database::MariaDB => unimplemented!("MariaDB driver not implemented"),
config::Database::SQLite => unimplemented!("SQLite driver not implemented"),
}
}
81 changes: 81 additions & 0 deletions src/database_drivers/sqlite.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use crate::database_drivers::DatabaseDriver;
use anyhow::Result;
use sqlx::sqlite::SqliteRow;
use sqlx::{Connection, Row, SqliteConnection};
use std::future::Future;
use std::pin::Pin;

pub struct SqliteDriver {
db: SqliteConnection,
}

impl<'a> SqliteDriver {
pub async fn new<'b>(db_url: &str) -> Result<SqliteDriver> {
let client = SqliteConnection::connect(db_url).await?;
Ok(SqliteDriver { db: client })
}
}

impl DatabaseDriver for SqliteDriver {
fn execute<'a>(
&'a mut self,
query: &'a str,
) -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + '_>> {
let fut = async move {
sqlx::query(query).execute(&mut self.db).await?;
Ok(())
};

Box::pin(fut)
}

fn get_or_create_schema_migrations(
&mut self,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, anyhow::Error>> + '_>> {
let fut = async move {
let query =
"CREATE TABLE IF NOT EXISTS schema_migrations (id VARCHAR(255) PRIMARY KEY)";
sqlx::query(query).execute(&mut self.db).await?;
let query = "SELECT id FROM schema_migrations ORDER BY id DESC";
let result: Vec<String> = sqlx::query(query)
.map(|row: SqliteRow| row.get("id"))
.fetch_all(&mut self.db)
.await?;

Ok(result)
};

Box::pin(fut)
}

fn insert_schema_migration<'a>(
&'a mut self,
id: &'a str,
) -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + '_>> {
let fut = async move {
sqlx::query("INSERT INTO schema_migrations (id) VALUES ($1)")
.bind(id)
.execute(&mut self.db)
.await?;
Ok(())
};

Box::pin(fut)
}

fn remove_schema_migration<'a>(
&'a mut self,
id: &'a str,
) -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + '_>> {
let fut = async move {
sqlx::query("delete from schema_migrations where id = $1")
.bind(id)
.execute(&mut self.db)
.await?;

Ok(())
};

Box::pin(fut)
}
}
21 changes: 20 additions & 1 deletion src/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ mod tests {
}

async fn test_migrate(database: Database, url: &str) -> Result<()> {
sleep(Duration::new(10, 0)).await; // we need to sleep to wait for the database server to start
let tmp_dir =
tempdir::TempDir::new(format!("test_migrate_{}", database.as_str()).as_str()).unwrap();
let migration_folder = tmp_dir.path();
Expand Down Expand Up @@ -260,21 +259,41 @@ mod tests {
#[test]
#[serial]
async fn test_migrate_libsql() -> Result<()> {
sleep(Duration::new(2, 0)).await; // we need to sleep to wait for the database server to start
let url = "http://localhost:6000";
test_migrate(Database::LibSQL, url).await
}

#[test]
#[serial]
async fn test_migrate_postgres() -> Result<()> {
sleep(Duration::new(2, 0)).await; // we need to sleep to wait for the database server to start
let url = "psql://postgres:mysecretpassword@localhost:6437/development?sslmode=disable";
test_migrate(Database::Postgres, url).await
}

#[test]
#[serial]
async fn test_migrate_mysql() -> Result<()> {
sleep(Duration::new(10, 0)).await; // we need to sleep to wait for the database server to start
let url = "mysql://root:password@localhost:3306/development";
test_migrate(Database::MySQL, url).await
}

#[test]
#[serial]
async fn test_migrate_sqlite() -> Result<()> {
let tmp_dir = tempdir::TempDir::new("temp_migrate_sqlite_db").unwrap();
let migration_folder = tmp_dir.path();
let migration_folder_string = migration_folder.to_str().unwrap();
let filename = format!("{migration_folder_string}/test.sqlite");
let filename_str = filename.as_str();
let path = std::path::Path::new(filename_str);

File::create(path)?;

let url = format!("sqlite://{}", path.to_str().unwrap());

test_migrate(Database::MySQL, url.as_str()).await
}
}

0 comments on commit 544ec6c

Please sign in to comment.