feat: Update dependencies and integrate k-core for database management

This commit is contained in:
2026-01-02 13:53:59 +01:00
parent 66e0e613fc
commit 1be64bb578
12 changed files with 158 additions and 211 deletions

137
Cargo.lock generated
View File

@@ -281,7 +281,7 @@ version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
dependencies = [ dependencies = [
"axum-core 0.5.5", "axum-core 0.5.6",
"axum-macros", "axum-macros",
"bytes", "bytes",
"form_urlencoded", "form_urlencoded",
@@ -331,9 +331,9 @@ dependencies = [
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.5.5" version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@@ -488,9 +488,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.46" version = "1.2.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -1007,15 +1007,16 @@ dependencies = [
[[package]] [[package]]
name = "fastembed" name = "fastembed"
version = "5.5.0" version = "5.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de72c516a1484c70ba0d98597dafc6274484b542c9ee54e7a326160baa013849" checksum = "899617d598766ef2135b6807d46c6c7ace87d8b39ae4e83a5dd50eb1a4eb6fc5"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hf-hub", "hf-hub",
"image", "image",
"ndarray", "ndarray",
"ort", "ort",
"safetensors",
"serde_json", "serde_json",
"tokenizers", "tokenizers",
] ]
@@ -1075,9 +1076,9 @@ dependencies = [
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.5" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
[[package]] [[package]]
name = "flate2" name = "flate2"
@@ -1769,9 +1770,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]] [[package]]
name = "iri-string" name = "iri-string"
version = "0.7.9" version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
dependencies = [ dependencies = [
"memchr", "memchr",
"serde", "serde",
@@ -1788,9 +1789,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.16" version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
@@ -1812,6 +1813,22 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "k-core"
version = "0.1.5"
source = "git+https://git.gabrielkaszewski.dev/GKaszewski/k-core#667cae596cf4e6c9c8e4cfa3bd5ee53ffb0796fb"
dependencies = [
"anyhow",
"chrono",
"serde",
"sqlx",
"thiserror 2.0.17",
"tower-sessions",
"tracing",
"tracing-subscriber",
"uuid",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -1851,13 +1868,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]] [[package]]
name = "libredox" name = "libredox"
version = "0.1.11" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
"redox_syscall 0.6.0", "redox_syscall 0.7.0",
] ]
[[package]] [[package]]
@@ -2061,7 +2078,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"openssl", "openssl",
"openssl-probe", "openssl-probe 0.1.6",
"openssl-sys", "openssl-sys",
"schannel", "schannel",
"security-framework 2.11.1", "security-framework 2.11.1",
@@ -2140,12 +2157,12 @@ dependencies = [
"axum-login", "axum-login",
"chrono", "chrono",
"dotenvy", "dotenvy",
"k-core",
"notes-domain", "notes-domain",
"notes-infra", "notes-infra",
"password-auth", "password-auth",
"serde", "serde",
"serde_json", "serde_json",
"sqlx",
"thiserror 2.0.17", "thiserror 2.0.17",
"time", "time",
"tokio", "tokio",
@@ -2185,6 +2202,7 @@ dependencies = [
"fastembed", "fastembed",
"futures-core", "futures-core",
"futures-util", "futures-util",
"k-core",
"notes-domain", "notes-domain",
"qdrant-client", "qdrant-client",
"serde", "serde",
@@ -2208,6 +2226,7 @@ dependencies = [
"chrono", "chrono",
"dotenvy", "dotenvy",
"futures-util", "futures-util",
"k-core",
"notes-domain", "notes-domain",
"notes-infra", "notes-infra",
"serde", "serde",
@@ -2396,6 +2415,12 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-probe"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391"
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.111" version = "0.9.111"
@@ -2592,9 +2617,9 @@ dependencies = [
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.12.0" version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
[[package]] [[package]]
name = "portable-atomic-util" name = "portable-atomic-util"
@@ -2653,9 +2678,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.103" version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -2984,9 +3009,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@@ -3100,22 +3125,19 @@ dependencies = [
[[package]] [[package]]
name = "rmp" name = "rmp"
version = "0.8.14" version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
dependencies = [ dependencies = [
"byteorder",
"num-traits", "num-traits",
"paste",
] ]
[[package]] [[package]]
name = "rmp-serde" name = "rmp-serde"
version = "1.3.0" version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
dependencies = [ dependencies = [
"byteorder",
"rmp", "rmp",
"serde", "serde",
] ]
@@ -3189,7 +3211,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe 0.1.6",
"rustls-pemfile", "rustls-pemfile",
"rustls-pki-types", "rustls-pki-types",
"schannel", "schannel",
@@ -3198,11 +3220,11 @@ dependencies = [
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.8.2" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe 0.2.0",
"rustls-pki-types", "rustls-pki-types",
"schannel", "schannel",
"security-framework 3.5.1", "security-framework 3.5.1",
@@ -3256,9 +3278,19 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.21" version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
[[package]]
name = "safetensors"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44560c11236a6130a46ce36c836a62936dc81ebf8c36a37947423571be0e55b6"
dependencies = [
"serde",
"serde_json",
]
[[package]] [[package]]
name = "schannel" name = "schannel"
@@ -3349,15 +3381,15 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.146" version = "1.0.148"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
"ryu",
"serde", "serde",
"serde_core", "serde_core",
"zmij",
] ]
[[package]] [[package]]
@@ -3442,10 +3474,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.6" version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [ dependencies = [
"errno",
"libc", "libc",
] ]
@@ -3616,6 +3649,7 @@ dependencies = [
"tokio-stream", "tokio-stream",
"tracing", "tracing",
"url", "url",
"uuid",
] ]
[[package]] [[package]]
@@ -3697,6 +3731,7 @@ dependencies = [
"thiserror 2.0.17", "thiserror 2.0.17",
"time", "time",
"tracing", "tracing",
"uuid",
"whoami", "whoami",
] ]
@@ -3736,6 +3771,7 @@ dependencies = [
"thiserror 2.0.17", "thiserror 2.0.17",
"time", "time",
"tracing", "tracing",
"uuid",
"whoami", "whoami",
] ]
@@ -3763,6 +3799,7 @@ dependencies = [
"time", "time",
"tracing", "tracing",
"url", "url",
"uuid",
] ]
[[package]] [[package]]
@@ -3802,9 +3839,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.111" version = "2.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -4143,7 +4180,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"prost", "prost",
"rustls-native-certs 0.8.2", "rustls-native-certs 0.8.3",
"rustls-pemfile", "rustls-pemfile",
"socket2 0.5.10", "socket2 0.5.10",
"tokio", "tokio",
@@ -4197,7 +4234,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "151b5a3e3c45df17466454bb74e9ecedecc955269bdedbf4d150dfa393b55a36" checksum = "151b5a3e3c45df17466454bb74e9ecedecc955269bdedbf4d150dfa393b55a36"
dependencies = [ dependencies = [
"axum-core 0.5.5", "axum-core 0.5.6",
"cookie", "cookie",
"futures-util", "futures-util",
"http", "http",
@@ -4263,7 +4300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce8cce604865576b7751b7a6bc3058f754569a60d689328bb74c52b1d87e355b" checksum = "ce8cce604865576b7751b7a6bc3058f754569a60d689328bb74c52b1d87e355b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core 0.5.5", "axum-core 0.5.6",
"base64 0.22.1", "base64 0.22.1",
"futures", "futures",
"http", "http",
@@ -5216,6 +5253,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "zmij"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de9211a9f64b825911bdf0240f58b7a8dac217fe260fc61f080a07f61372fbd5"
[[package]] [[package]]
name = "zune-core" name = "zune-core"
version = "0.4.12" version = "0.4.12"

View File

@@ -1,3 +1,3 @@
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["notes-api", "notes-domain", "notes-infra", "notes-worker"] members = [ "notes-api", "notes-domain", "notes-infra", "notes-worker"]

View File

@@ -9,12 +9,10 @@ default = ["sqlite", "smart-features"]
sqlite = [ sqlite = [
"notes-infra/sqlite", "notes-infra/sqlite",
"tower-sessions-sqlx-store/sqlite", "tower-sessions-sqlx-store/sqlite",
"sqlx/sqlite",
] ]
postgres = [ postgres = [
"notes-infra/postgres", "notes-infra/postgres",
"tower-sessions-sqlx-store/postgres", "tower-sessions-sqlx-store/postgres",
"sqlx/postgres",
] ]
smart-features = ["notes-infra/smart-features", "notes-infra/broker-nats"] smart-features = ["notes-infra/smart-features", "notes-infra/broker-nats"]
@@ -59,6 +57,9 @@ uuid = { version = "1.19.0", features = ["v4", "serde"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
# Database
sqlx = { version = "0.8.6", features = ["sqlite", "runtime-tokio"] }
dotenvy = "0.15.7" dotenvy = "0.15.7"
k-core = { git = "https://git.gabrielkaszewski.dev/GKaszewski/k-core", features = [
"logging",
"db-sqlx",
] }

View File

@@ -2,7 +2,8 @@
//! //!
//! A high-performance, self-hosted note-taking API following hexagonal architecture. //! A high-performance, self-hosted note-taking API following hexagonal architecture.
use std::sync::Arc; use k_core::db::DatabasePool;
use std::{sync::Arc, time::Duration as StdDuration};
use time::Duration; use time::Duration;
use axum::Router; use axum::Router;
@@ -10,9 +11,8 @@ use axum_login::AuthManagerLayerBuilder;
use tower_http::cors::CorsLayer; use tower_http::cors::CorsLayer;
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tower_sessions::{Expiry, SessionManagerLayer}; use tower_sessions::{Expiry, SessionManagerLayer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use notes_infra::{DatabaseConfig, run_migrations}; use notes_infra::run_migrations;
mod auth; mod auth;
mod config; mod config;
@@ -27,55 +27,45 @@ use state::AppState;
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
// Initialize tracing k_core::logging::init("notes_api");
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "notes_api=debug,tower_http=debug,axum_login=debug".into()),
)
.with(tracing_subscriber::fmt::layer())
.init();
// Load configuration // Load configuration
let config = Config::from_env(); let config = Config::from_env();
// Setup database // Setup database
tracing::info!("Connecting to database: {}", config.database_url); tracing::info!("Connecting to database: {}", config.database_url);
let db_config = DatabaseConfig::new(&config.database_url); let db_config = k_core::db::DatabaseConfig {
url: config.database_url.clone(),
max_connections: 5,
min_connections: 1,
acquire_timeout: StdDuration::from_secs(30),
};
let db_pool = k_core::db::connect(&db_config).await?;
run_migrations(&db_pool).await?;
#[cfg(feature = "smart-features")] #[cfg(feature = "smart-features")]
use notes_infra::factory::build_link_repository; use notes_infra::factory::build_link_repository;
use notes_infra::factory::{ use notes_infra::factory::{
build_database_pool, build_note_repository, build_session_store, build_tag_repository, build_note_repository, build_session_store, build_tag_repository, build_user_repository,
build_user_repository,
}; };
let pool = build_database_pool(&db_config)
.await
.map_err(|e| anyhow::anyhow!(e))?;
// Run migrations
if let Err(e) = run_migrations(&pool).await {
tracing::warn!(
"Migration error (might be expected if not implemented for this DB): {}",
e
);
}
// Create a default user for development // Create a default user for development
create_dev_user(&pool).await.ok(); create_dev_user(&db_pool).await.ok();
// Create repositories via factory // Create repositories via factory
let note_repo = build_note_repository(&pool) let note_repo = build_note_repository(&db_pool)
.await .await
.map_err(|e| anyhow::anyhow!(e))?; .map_err(|e| anyhow::anyhow!(e))?;
let tag_repo = build_tag_repository(&pool) let tag_repo = build_tag_repository(&db_pool)
.await .await
.map_err(|e| anyhow::anyhow!(e))?; .map_err(|e| anyhow::anyhow!(e))?;
let user_repo = build_user_repository(&pool) let user_repo = build_user_repository(&db_pool)
.await .await
.map_err(|e| anyhow::anyhow!(e))?; .map_err(|e| anyhow::anyhow!(e))?;
#[cfg(feature = "smart-features")] #[cfg(feature = "smart-features")]
let link_repo = build_link_repository(&pool) let link_repo = build_link_repository(&db_pool)
.await .await
.map_err(|e| anyhow::anyhow!(e))?; .map_err(|e| anyhow::anyhow!(e))?;
@@ -127,7 +117,7 @@ async fn main() -> anyhow::Result<()> {
// Session layer // Session layer
// Use the factory to build the session store, agnostic of the underlying DB // Use the factory to build the session store, agnostic of the underlying DB
let session_store = build_session_store(&pool) let session_store = build_session_store(&db_pool)
.await .await
.map_err(|e| anyhow::anyhow!(e))?; .map_err(|e| anyhow::anyhow!(e))?;
session_store session_store
@@ -189,7 +179,7 @@ async fn main() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
async fn create_dev_user(pool: &notes_infra::db::DatabasePool) -> anyhow::Result<()> { async fn create_dev_user(pool: &DatabasePool) -> anyhow::Result<()> {
use notes_domain::{Email, User}; use notes_domain::{Email, User};
use notes_infra::factory::build_user_repository; use notes_infra::factory::build_user_repository;
use password_auth::generate_hash; use password_auth::generate_hash;

View File

@@ -28,3 +28,8 @@ serde = { version = "1.0", features = ["derive"] }
async-nats = { version = "0.45", optional = true } async-nats = { version = "0.45", optional = true }
futures-util = { version = "0.3", optional = true } futures-util = { version = "0.3", optional = true }
futures-core = "0.3" futures-core = "0.3"
k-core = { git = "https://git.gabrielkaszewski.dev/GKaszewski/k-core", features = [
"logging",
"db-sqlx",
"sqlite"
], version = "*"}

View File

@@ -1,102 +1,19 @@
//! Database connection pool management //! Database connection pool management
use sqlx::Pool; use k_core::db::DatabasePool;
#[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)
}
/// Run database migrations /// Run database migrations
pub async fn run_migrations(pool: &DatabasePool) -> Result<(), sqlx::Error> { pub async fn run_migrations(pool: &DatabasePool) -> Result<(), sqlx::Error> {
match pool { match pool {
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
DatabasePool::Sqlite(pool) => { DatabasePool::Sqlite(pool) => {
// Point specifically to the sqlite folder
sqlx::migrate!("../migrations").run(pool).await?; sqlx::migrate!("../migrations").run(pool).await?;
} }
#[cfg(feature = "postgres")] #[cfg(feature = "postgres")]
DatabasePool::Postgres(_pool) => { DatabasePool::Postgres(pool) => {
// Placeholder for Postgres migrations // Point specifically to the postgres folder
// sqlx::migrate!("../migrations/postgres").run(_pool).await?; 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(),
));
} }
} }
@@ -110,17 +27,16 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_create_in_memory_pool() { async fn test_create_in_memory_pool() {
let config = DatabaseConfig::in_memory(); let config = k_core::db::DatabaseConfig::in_memory();
let pool = create_pool(&config).await; let pool = k_core::db::connect(&config).await;
assert!(pool.is_ok()); assert!(pool.is_ok());
} }
#[tokio::test] #[tokio::test]
async fn test_run_migrations() { async fn test_run_migrations() {
let config = DatabaseConfig::in_memory(); let config = k_core::db::DatabaseConfig::in_memory();
let pool = create_pool(&config).await.unwrap(); let pool = k_core::db::connect(&config).await.unwrap();
let db_pool = DatabasePool::Sqlite(pool); let result = run_migrations(&pool).await;
let result = run_migrations(&db_pool).await;
assert!(result.is_ok()); assert!(result.is_ok());
} }
} }

View File

@@ -1,8 +1,9 @@
use std::sync::Arc; use std::sync::Arc;
use crate::{DatabaseConfig, db::DatabasePool};
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
use crate::{SqliteNoteRepository, SqliteTagRepository, SqliteUserRepository}; use crate::{SqliteNoteRepository, SqliteTagRepository, SqliteUserRepository};
use k_core::db::DatabaseConfig;
use k_core::db::DatabasePool;
use notes_domain::{NoteRepository, TagRepository, UserRepository}; use notes_domain::{NoteRepository, TagRepository, UserRepository};
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@@ -96,9 +97,6 @@ pub async fn build_link_repository(
DatabasePool::Sqlite(pool) => Ok(Arc::new( DatabasePool::Sqlite(pool) => Ok(Arc::new(
crate::link_repository::SqliteLinkRepository::new(pool.clone()), crate::link_repository::SqliteLinkRepository::new(pool.clone()),
)), )),
_ => Err(FactoryError::NotImplemented(
"LinkRepostiory for non-sqlite".to_string(),
)),
} }
} }

View File

@@ -11,7 +11,6 @@
//! //!
//! ## Database //! ## Database
//! //!
//! - [`db::create_pool`] - Create a database connection pool
//! - [`db::run_migrations`] - Run database migrations //! - [`db::run_migrations`] - Run database migrations
#[cfg(feature = "broker-nats")] #[cfg(feature = "broker-nats")]
@@ -33,9 +32,7 @@ pub mod user_repository;
pub mod vector; pub mod vector;
// Re-export for convenience // Re-export for convenience
#[cfg(feature = "sqlite")] pub use db::run_migrations;
pub use db::create_pool;
pub use db::{DatabaseConfig, run_migrations};
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
pub use link_repository::SqliteLinkRepository; pub use link_repository::SqliteLinkRepository;
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]

View File

@@ -162,16 +162,16 @@ impl TagRepository for SqliteTagRepository {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::db::{DatabaseConfig, DatabasePool, create_pool, run_migrations}; use crate::db::run_migrations;
use crate::user_repository::SqliteUserRepository; use crate::user_repository::SqliteUserRepository;
use k_core::db::DatabaseConfig;
use notes_domain::{Email, User, UserRepository}; use notes_domain::{Email, User, UserRepository};
async fn setup_test_db() -> SqlitePool { async fn setup_test_db() -> SqlitePool {
let config = DatabaseConfig::in_memory(); let config = DatabaseConfig::in_memory();
let pool = create_pool(&config).await.unwrap(); let pool = k_core::db::connect(&config).await.unwrap();
let db_pool = DatabasePool::Sqlite(pool.clone()); run_migrations(&pool).await.unwrap();
run_migrations(&db_pool).await.unwrap(); pool.sqlite_pool().unwrap().clone()
pool
} }
async fn create_test_user(pool: &SqlitePool) -> User { async fn create_test_user(pool: &SqlitePool) -> User {

View File

@@ -136,15 +136,16 @@ impl UserRepository for SqliteUserRepository {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use k_core::db::DatabaseConfig;
use super::*; use super::*;
use crate::db::{DatabaseConfig, DatabasePool, create_pool, run_migrations}; use crate::db::run_migrations;
async fn setup_test_db() -> SqlitePool { async fn setup_test_db() -> SqlitePool {
let config = DatabaseConfig::in_memory(); let config = DatabaseConfig::in_memory();
let pool = create_pool(&config).await.unwrap(); let pool = k_core::db::connect(&config).await.unwrap();
let db_pool = DatabasePool::Sqlite(pool.clone()); run_migrations(&pool).await.unwrap();
run_migrations(&db_pool).await.unwrap(); pool.sqlite_pool().unwrap().clone()
pool
} }
#[tokio::test] #[tokio::test]

View File

@@ -30,3 +30,8 @@ async-trait = "0.1.89"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
dotenvy = "0.15.7" dotenvy = "0.15.7"
k-core = { git = "https://git.gabrielkaszewski.dev/GKaszewski/k-core", features = [
"logging",
"db-sqlx",
"sqlite"
], version = "*"}

View File

@@ -2,35 +2,26 @@ use futures_util::StreamExt;
#[cfg(feature = "smart-features")] #[cfg(feature = "smart-features")]
use notes_domain::services::SmartNoteService; use notes_domain::services::SmartNoteService;
#[cfg(feature = "smart-features")] #[cfg(feature = "smart-features")]
use notes_infra::{ use notes_infra::factory::{
DatabaseConfig, BrokerProvider, build_database_pool, build_embedding_generator, build_link_repository,
factory::{ build_message_broker, build_vector_store,
BrokerProvider, build_database_pool, build_embedding_generator, build_link_repository,
build_message_broker, build_vector_store,
},
}; };
use crate::config::Config; use crate::config::Config;
mod config; mod config;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
tracing_subscriber::registry() k_core::logging::init("notes_worker");
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "notes_worker=info,notes_infra=info".into()),
)
.with(tracing_subscriber::fmt::layer())
.init();
let config = Config::from_env(); let config = Config::from_env();
#[cfg(feature = "smart-features")] #[cfg(feature = "smart-features")]
{ {
// Connect to message broker via factory // Connect to message broker via factory
use k_core::db::DatabaseConfig;
tracing::info!("Connecting to message broker: {}", config.broker_url); tracing::info!("Connecting to message broker: {}", config.broker_url);
let broker_provider = BrokerProvider::Nats { let broker_provider = BrokerProvider::Nats {
url: config.broker_url.clone(), url: config.broker_url.clone(),