aboutsummaryrefslogtreecommitdiff
path: root/src/db/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/db/mod.rs')
-rw-r--r--src/db/mod.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/db/mod.rs b/src/db/mod.rs
new file mode 100644
index 0000000..37769d2
--- /dev/null
+++ b/src/db/mod.rs
@@ -0,0 +1,47 @@
+use anyhow::{Error, Result};
+use rusqlite_migration::{Migrations, M};
+use tokio_rusqlite::Connection;
+
+pub mod files;
+mod utils;
+
+pub async fn init(path: &str) -> Result<Connection> {
+ let connection = Connection::open(path)
+ .await
+ .map_err(|err| Error::msg(format!("Error opening connection: {err}")))?;
+
+ apply_migrations(&connection).await?;
+ set_pragma(&connection, "foreign_keys", "ON").await?;
+ set_pragma(&connection, "journal_mode", "wal").await?;
+ Ok(connection)
+}
+
+async fn apply_migrations(conn: &Connection) -> Result<()> {
+ let migrations = Migrations::new(vec![
+ M::up(include_str!("migrations/01-init.sql")),
+ M::up(include_str!("migrations/02-strict-tables.sql")),
+ ]);
+
+ Ok(conn
+ .call(move |conn| {
+ migrations
+ .to_latest(conn)
+ .map_err(|migration_err| tokio_rusqlite::Error::Other(Box::new(migration_err)))
+ })
+ .await?)
+}
+
+async fn set_pragma(
+ conn: &Connection,
+ key: impl Into<String>,
+ value: impl Into<String>,
+) -> Result<()> {
+ let key = key.into();
+ let value = value.into();
+ Ok(conn
+ .call(move |conn| {
+ conn.pragma_update(None, &key, &value)
+ .map_err(tokio_rusqlite::Error::Rusqlite)
+ })
+ .await?)
+}