feat: Update dependencies and integrate k-core for database management
This commit is contained in:
@@ -28,3 +28,8 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
async-nats = { version = "0.45", optional = true }
|
||||
futures-util = { version = "0.3", optional = true }
|
||||
futures-core = "0.3"
|
||||
k-core = { git = "https://git.gabrielkaszewski.dev/GKaszewski/k-core", features = [
|
||||
"logging",
|
||||
"db-sqlx",
|
||||
"sqlite"
|
||||
], version = "*"}
|
||||
@@ -1,102 +1,19 @@
|
||||
//! Database connection pool management
|
||||
|
||||
use sqlx::Pool;
|
||||
#[cfg(feature = "postgres")]
|
||||
use sqlx::Postgres;
|
||||
#[cfg(feature = "sqlite")]
|
||||
use sqlx::Sqlite;
|
||||
#[cfg(feature = "sqlite")]
|
||||
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
|
||||
#[cfg(feature = "sqlite")]
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Configuration for the database connection
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DatabaseConfig {
|
||||
pub url: String,
|
||||
pub max_connections: u32,
|
||||
pub min_connections: u32,
|
||||
pub acquire_timeout: Duration,
|
||||
}
|
||||
|
||||
impl Default for DatabaseConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
url: "sqlite:data.db?mode=rwc".to_string(),
|
||||
max_connections: 5,
|
||||
min_connections: 1,
|
||||
acquire_timeout: Duration::from_secs(5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseConfig {
|
||||
pub fn new(url: impl Into<String>) -> Self {
|
||||
Self {
|
||||
url: url.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_memory() -> Self {
|
||||
Self {
|
||||
url: "sqlite::memory:".to_string(),
|
||||
max_connections: 1, // SQLite in-memory is single-connection
|
||||
min_connections: 1,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DatabasePool {
|
||||
#[cfg(feature = "sqlite")]
|
||||
Sqlite(Pool<Sqlite>),
|
||||
#[cfg(feature = "postgres")]
|
||||
Postgres(Pool<Postgres>),
|
||||
}
|
||||
|
||||
/// Create a database connection pool
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub async fn create_pool(config: &DatabaseConfig) -> Result<SqlitePool, sqlx::Error> {
|
||||
let options = SqliteConnectOptions::from_str(&config.url)?
|
||||
.create_if_missing(true)
|
||||
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
||||
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
|
||||
.busy_timeout(Duration::from_secs(30));
|
||||
|
||||
let pool = SqlitePoolOptions::new()
|
||||
.max_connections(config.max_connections)
|
||||
.min_connections(config.min_connections)
|
||||
.acquire_timeout(config.acquire_timeout)
|
||||
.connect_with(options)
|
||||
.await?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
use k_core::db::DatabasePool;
|
||||
|
||||
/// Run database migrations
|
||||
pub async fn run_migrations(pool: &DatabasePool) -> Result<(), sqlx::Error> {
|
||||
match pool {
|
||||
#[cfg(feature = "sqlite")]
|
||||
DatabasePool::Sqlite(pool) => {
|
||||
// Point specifically to the sqlite folder
|
||||
sqlx::migrate!("../migrations").run(pool).await?;
|
||||
}
|
||||
#[cfg(feature = "postgres")]
|
||||
DatabasePool::Postgres(_pool) => {
|
||||
// Placeholder for Postgres migrations
|
||||
// sqlx::migrate!("../migrations/postgres").run(_pool).await?;
|
||||
tracing::warn!("Postgres migrations not yet implemented");
|
||||
return Err(sqlx::Error::Configuration(
|
||||
"Postgres migrations not yet implemented".into(),
|
||||
));
|
||||
}
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => {
|
||||
return Err(sqlx::Error::Configuration(
|
||||
"No database feature enabled".into(),
|
||||
));
|
||||
DatabasePool::Postgres(pool) => {
|
||||
// Point specifically to the postgres folder
|
||||
sqlx::migrate!("../migrations_postgres").run(pool).await?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,17 +27,16 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_in_memory_pool() {
|
||||
let config = DatabaseConfig::in_memory();
|
||||
let pool = create_pool(&config).await;
|
||||
let config = k_core::db::DatabaseConfig::in_memory();
|
||||
let pool = k_core::db::connect(&config).await;
|
||||
assert!(pool.is_ok());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_run_migrations() {
|
||||
let config = DatabaseConfig::in_memory();
|
||||
let pool = create_pool(&config).await.unwrap();
|
||||
let db_pool = DatabasePool::Sqlite(pool);
|
||||
let result = run_migrations(&db_pool).await;
|
||||
let config = k_core::db::DatabaseConfig::in_memory();
|
||||
let pool = k_core::db::connect(&config).await.unwrap();
|
||||
let result = run_migrations(&pool).await;
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{DatabaseConfig, db::DatabasePool};
|
||||
#[cfg(feature = "sqlite")]
|
||||
use crate::{SqliteNoteRepository, SqliteTagRepository, SqliteUserRepository};
|
||||
use k_core::db::DatabaseConfig;
|
||||
use k_core::db::DatabasePool;
|
||||
use notes_domain::{NoteRepository, TagRepository, UserRepository};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
@@ -96,9 +97,6 @@ pub async fn build_link_repository(
|
||||
DatabasePool::Sqlite(pool) => Ok(Arc::new(
|
||||
crate::link_repository::SqliteLinkRepository::new(pool.clone()),
|
||||
)),
|
||||
_ => Err(FactoryError::NotImplemented(
|
||||
"LinkRepostiory for non-sqlite".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
//!
|
||||
//! ## Database
|
||||
//!
|
||||
//! - [`db::create_pool`] - Create a database connection pool
|
||||
//! - [`db::run_migrations`] - Run database migrations
|
||||
|
||||
#[cfg(feature = "broker-nats")]
|
||||
@@ -33,9 +32,7 @@ pub mod user_repository;
|
||||
pub mod vector;
|
||||
|
||||
// Re-export for convenience
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub use db::create_pool;
|
||||
pub use db::{DatabaseConfig, run_migrations};
|
||||
pub use db::run_migrations;
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub use link_repository::SqliteLinkRepository;
|
||||
#[cfg(feature = "sqlite")]
|
||||
|
||||
@@ -162,16 +162,16 @@ impl TagRepository for SqliteTagRepository {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::db::{DatabaseConfig, DatabasePool, create_pool, run_migrations};
|
||||
use crate::db::run_migrations;
|
||||
use crate::user_repository::SqliteUserRepository;
|
||||
use k_core::db::DatabaseConfig;
|
||||
use notes_domain::{Email, User, UserRepository};
|
||||
|
||||
async fn setup_test_db() -> SqlitePool {
|
||||
let config = DatabaseConfig::in_memory();
|
||||
let pool = create_pool(&config).await.unwrap();
|
||||
let db_pool = DatabasePool::Sqlite(pool.clone());
|
||||
run_migrations(&db_pool).await.unwrap();
|
||||
pool
|
||||
let pool = k_core::db::connect(&config).await.unwrap();
|
||||
run_migrations(&pool).await.unwrap();
|
||||
pool.sqlite_pool().unwrap().clone()
|
||||
}
|
||||
|
||||
async fn create_test_user(pool: &SqlitePool) -> User {
|
||||
|
||||
@@ -136,15 +136,16 @@ impl UserRepository for SqliteUserRepository {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use k_core::db::DatabaseConfig;
|
||||
|
||||
use super::*;
|
||||
use crate::db::{DatabaseConfig, DatabasePool, create_pool, run_migrations};
|
||||
use crate::db::run_migrations;
|
||||
|
||||
async fn setup_test_db() -> SqlitePool {
|
||||
let config = DatabaseConfig::in_memory();
|
||||
let pool = create_pool(&config).await.unwrap();
|
||||
let db_pool = DatabasePool::Sqlite(pool.clone());
|
||||
run_migrations(&db_pool).await.unwrap();
|
||||
pool
|
||||
let pool = k_core::db::connect(&config).await.unwrap();
|
||||
run_migrations(&pool).await.unwrap();
|
||||
pool.sqlite_pool().unwrap().clone()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user