diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index dade483e..96fdd1f0 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -44,4 +44,4 @@ jobs: # Layering guards. These live in the Makefile and were previously local-only, # so a PR could go green in CI while violating them. - name: guards - run: make check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-social-crates-are-ap-free + run: make check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-sqlite-is-ap-free diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6dee4da..91f1eef6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: # Layering guards. These live in the Makefile and were previously local-only, # so a PR could go green in CI while violating them. - name: guards - run: make check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-social-crates-are-ap-free + run: make check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-sqlite-is-ap-free docker: name: Build & Push Docker Image diff --git a/Cargo.lock b/Cargo.lock index f719e86f..378715aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,17 +220,6 @@ dependencies = [ "url", ] -[[package]] -name = "adapter-common" -version = "0.1.0" -dependencies = [ - "chrono", - "domain", - "sqlx", - "tracing", - "uuid", -] - [[package]] name = "adler2" version = "2.0.1" @@ -1148,10 +1137,7 @@ dependencies = [ "plex", "poster-fetcher", "sqlite", - "sqlite-event-queue", "sqlite-federation", - "sqlite-search", - "sqlite-social", "sqlx", "tokio", "tracing", @@ -4950,10 +4936,7 @@ dependencies = [ "rss 0.1.0", "serde_json", "sqlite", - "sqlite-event-queue", "sqlite-federation", - "sqlite-search", - "sqlite-social", "sqlx", "tokio", "tower", @@ -5195,18 +5178,16 @@ dependencies = [ name = "sqlite" version = "0.1.0" dependencies = [ - "adapter-common", "anyhow", "async-stream", "async-trait", "bytes", "chrono", "domain", + "event-payload", "futures", "serde", "serde_json", - "sqlite-event-queue", - "sqlite-social", "sqlx", "tempfile", "tokio", @@ -5214,65 +5195,24 @@ dependencies = [ "uuid", ] -[[package]] -name = "sqlite-event-queue" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "domain", - "event-payload", - "futures", - "serde_json", - "sqlx", - "tokio", - "tracing", -] - [[package]] name = "sqlite-federation" version = "0.1.0" dependencies = [ "activitypub", - "adapter-common", "anyhow", "async-trait", "chrono", "domain", "k-ap", "serde_json", - "sqlite-social", + "sqlite", "sqlx", "tokio", "tracing", "uuid", ] -[[package]] -name = "sqlite-search" -version = "0.1.0" -dependencies = [ - "adapter-common", - "async-trait", - "domain", - "sqlx", - "tokio", - "uuid", -] - -[[package]] -name = "sqlite-social" -version = "0.1.0" -dependencies = [ - "adapter-common", - "async-trait", - "chrono", - "domain", - "sqlx", - "tokio", - "uuid", -] - [[package]] name = "sqlx" version = "0.8.6" @@ -7206,9 +7146,7 @@ dependencies = [ "poster-fetcher", "poster-sync", "sqlite", - "sqlite-event-queue", "sqlite-federation", - "sqlite-search", "sqlx", "tmdb-enrichment", "tokio", diff --git a/Cargo.toml b/Cargo.toml index ca6a2d76..e38ee522 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,6 @@ members = [ "crates/adapters/rss", "crates/adapters/sqlite", "crates/adapters/sqlite-federation", - "crates/adapters/sqlite-social", - "crates/adapters/sqlite-event-queue", "crates/adapters/template-askama", "crates/adapters/activitypub", "crates/adapters/export", @@ -29,8 +27,6 @@ members = [ "crates/adapters/importer", "crates/adapters/jellyfin", "crates/adapters/plex", - "crates/adapters/sqlite-search", - "crates/adapters/adapter-common", "crates/infra-wiring", ] resolver = "2" @@ -84,18 +80,14 @@ rss = { path = "crates/adapters/rss" } export = { path = "crates/adapters/export" } sqlite = { path = "crates/adapters/sqlite" } sqlite-federation = { path = "crates/adapters/sqlite-federation" } -sqlite-social = { path = "crates/adapters/sqlite-social" } template-askama = { path = "crates/adapters/template-askama" } activitypub = { path = "crates/adapters/activitypub" } event-payload = { path = "crates/adapters/event-payload" } nats = { path = "crates/adapters/nats" } -sqlite-event-queue = { path = "crates/adapters/sqlite-event-queue" } importer = { path = "crates/adapters/importer" } jellyfin = { path = "crates/adapters/jellyfin" } plex = { path = "crates/adapters/plex" } image-converter = { path = "crates/adapters/image-converter" } -sqlite-search = { path = "crates/adapters/sqlite-search" } -adapter-common = { path = "crates/adapters/adapter-common" } infra-wiring = { path = "crates/infra-wiring" } [profile.dev] diff --git a/Dockerfile b/Dockerfile index aed95f52..1b4c67bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,8 +34,6 @@ COPY crates/adapters/plex/Cargo.toml crates/adapters/plex/Cargo.tom COPY crates/adapters/rss/Cargo.toml crates/adapters/rss/Cargo.toml COPY crates/adapters/sqlite/Cargo.toml crates/adapters/sqlite/Cargo.toml COPY crates/adapters/sqlite-federation/Cargo.toml crates/adapters/sqlite-federation/Cargo.toml -COPY crates/adapters/sqlite-social/Cargo.toml crates/adapters/sqlite-social/Cargo.toml -COPY crates/adapters/sqlite-event-queue/Cargo.toml crates/adapters/sqlite-event-queue/Cargo.toml COPY crates/adapters/template-askama/Cargo.toml crates/adapters/template-askama/Cargo.toml COPY crates/api-types/Cargo.toml crates/api-types/Cargo.toml COPY crates/application/Cargo.toml crates/application/Cargo.toml @@ -46,8 +44,6 @@ COPY crates/presentation/Cargo.toml crates/presentation/Cargo.toml COPY crates/server/Cargo.toml crates/server/Cargo.toml COPY crates/tui/Cargo.toml crates/tui/Cargo.toml COPY crates/adapters/image-converter/Cargo.toml crates/adapters/image-converter/Cargo.toml -COPY crates/adapters/sqlite-search/Cargo.toml crates/adapters/sqlite-search/Cargo.toml -COPY crates/adapters/adapter-common/Cargo.toml crates/adapters/adapter-common/Cargo.toml COPY crates/worker/Cargo.toml crates/worker/Cargo.toml COPY crates/infra-wiring/Cargo.toml crates/infra-wiring/Cargo.toml diff --git a/Makefile b/Makefile index caef6984..82b878ba 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .DEFAULT_GOAL := check -check: fmt-check clippy test check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-social-crates-are-ap-free +check: fmt-check clippy test check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-sqlite-is-ap-free @echo "✅ All checks passed" check-appcontext: @@ -59,13 +59,13 @@ check-federation-off-social: @echo "✅ server wires real social behavior in every configuration" -check-social-crates-are-ap-free: - @if grep -nE '^[[:space:]]*(k-ap|activitypub[A-Za-z0-9_-]*|[A-Za-z0-9_-]+-federation)[[:space:]]*=' crates/adapters/*-social/Cargo.toml | grep -q .; then \ - echo "❌ social crate depends on ActivityPub:"; \ - grep -nE '^[[:space:]]*(k-ap|activitypub[A-Za-z0-9_-]*|[A-Za-z0-9_-]+-federation)[[:space:]]*=' crates/adapters/*-social/Cargo.toml; \ +check-sqlite-is-ap-free: + @if grep -nE '^[[:space:]]*(k-ap|activitypub[A-Za-z0-9_-]*|[A-Za-z0-9_-]+-federation)[[:space:]]*=' crates/adapters/sqlite/Cargo.toml | grep -q .; then \ + echo "❌ sqlite crate depends on ActivityPub:"; \ + grep -nE '^[[:space:]]*(k-ap|activitypub[A-Za-z0-9_-]*|[A-Za-z0-9_-]+-federation)[[:space:]]*=' crates/adapters/sqlite/Cargo.toml; \ exit 1; \ fi - @echo "✅ social crates depend on no k-ap, activitypub, or *-federation crate" + @echo "✅ sqlite crate depends on no k-ap, activitypub, or *-federation crate" fmt: cargo fmt @@ -106,4 +106,4 @@ dev-spa: spa-dev: @npm --prefix spa run dev -.PHONY: check fmt fmt-check clippy test fix dev dev-stop dev-worker dev-spa spa-dev check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-social-crates-are-ap-free +.PHONY: check fmt fmt-check clippy test fix dev dev-stop dev-worker dev-spa spa-dev check-appcontext check-handler-deps check-handler-repos check-presentation-adapters check-federation-off-social check-sqlite-is-ap-free diff --git a/README.md b/README.md index df522568..9a316e2c 100644 --- a/README.md +++ b/README.md @@ -98,9 +98,8 @@ presentation — Axum HTTP router, OpenAPI spec assembly, Swagger UI + Sc server — owns the HTTP binary, features (federation, nats), boots presentation's router worker — standalone worker binary (event consumer, poster sync, federation) adapters/ - adapter-common — shared row-to-domain conversions, sqlx error mapping, date/uuid parsing utils auth — JWT issuance and validation (Argon2 passwords) - sqlite — SQLite repository + connection factory + sqlite — SQLite repositories, search (FTS5), social graph, durable event queue, connection factory + migrations metadata — TMDB / OMDb HTTP client poster-fetcher — downloads poster images object-storage — stores images (posters + user avatars) on local filesystem or S3-compatible storage @@ -114,11 +113,9 @@ adapters/ jellyfin — Jellyfin webhook payload parser (MediaServerParser adapter) plex — Plex webhook payload parser (MediaServerParser adapter; requires Plex Pass) event-payload — shared event serialization DTOs (used by all event bus adapters) - sqlite-event-queue — durable polling event queue backed by SQLite event-publisher — in-memory event channel (used in tests) nats — NATS Core / JetStream event publisher and consumer activitypub — ActivityPub federation adapter (follow, inbox/outbox, actor); delegates to k-ap for protocol internals - sqlite-search — SQLite FTS5 implementation of SearchPort + SearchCommand sqlite-federation — SQLite-backed federation repository tui — terminal UI client (ratatui); shares api-types with presentation for typed API access spa/ — React SPA (TanStack Router + shadcn/ui + Vite); served at /app/ by the backend diff --git a/crates/adapters/adapter-common/Cargo.toml b/crates/adapters/adapter-common/Cargo.toml deleted file mode 100644 index fe6f793c..00000000 --- a/crates/adapters/adapter-common/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "adapter-common" -version = "0.1.0" -edition.workspace = true - -[dependencies] -domain = { workspace = true } -sqlx = { workspace = true } -tracing = { workspace = true } -chrono = { workspace = true } -uuid = { workspace = true } diff --git a/crates/adapters/sqlite-event-queue/Cargo.toml b/crates/adapters/sqlite-event-queue/Cargo.toml deleted file mode 100644 index df685810..00000000 --- a/crates/adapters/sqlite-event-queue/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "sqlite-event-queue" -version = "0.1.0" -edition.workspace = true - -[dependencies] -sqlx = { workspace = true, features = ["macros", "chrono"] } -domain = { workspace = true } -event-payload = { workspace = true } -anyhow = { workspace = true } -async-trait = { workspace = true } -serde_json = { workspace = true } -tokio = { workspace = true } -futures = { workspace = true } -tracing = { workspace = true } diff --git a/crates/adapters/sqlite-event-queue/src/migrations.rs b/crates/adapters/sqlite-event-queue/src/migrations.rs deleted file mode 100644 index 56c89219..00000000 --- a/crates/adapters/sqlite-event-queue/src/migrations.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub(crate) async fn run(pool: &sqlx::SqlitePool) -> anyhow::Result<()> { - sqlx::migrate!("./migrations") - .set_ignore_missing(true) - .run(pool) - .await - .map_err(|e| anyhow::anyhow!("sqlite-event-queue migration failed: {e}")) -} diff --git a/crates/adapters/sqlite-federation/Cargo.toml b/crates/adapters/sqlite-federation/Cargo.toml index 573f19ad..0f7549f1 100644 --- a/crates/adapters/sqlite-federation/Cargo.toml +++ b/crates/adapters/sqlite-federation/Cargo.toml @@ -6,9 +6,8 @@ edition.workspace = true [dependencies] sqlx = { workspace = true } activitypub = { workspace = true } -adapter-common = { workspace = true } k-ap = { version = "0.5.0", registry = "gitea" } -sqlite-social = { workspace = true } +sqlite = { workspace = true } domain = { workspace = true } anyhow = { workspace = true } serde_json = { workspace = true } diff --git a/crates/adapters/sqlite-federation/src/activity.rs b/crates/adapters/sqlite-federation/src/activity.rs index 779b707e..a16b84e8 100644 --- a/crates/adapters/sqlite-federation/src/activity.rs +++ b/crates/adapters/sqlite-federation/src/activity.rs @@ -4,7 +4,7 @@ use chrono::Utc; use k_ap::ActivityRepository; use super::SqliteFederationRepository; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl ActivityRepository for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-federation/src/actor.rs b/crates/adapters/sqlite-federation/src/actor.rs index 7ed39616..d25d50cd 100644 --- a/crates/adapters/sqlite-federation/src/actor.rs +++ b/crates/adapters/sqlite-federation/src/actor.rs @@ -5,7 +5,7 @@ use k_ap::{AnnounceRepository, Keypair, KeypairRepository, RemoteActor, RemoteAc use sqlx::Row; use super::{SqliteFederationRepository, remote_actor_from_row}; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl KeypairRepository for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-federation/src/blocklist.rs b/crates/adapters/sqlite-federation/src/blocklist.rs index 2785c9f8..9f5daff1 100644 --- a/crates/adapters/sqlite-federation/src/blocklist.rs +++ b/crates/adapters/sqlite-federation/src/blocklist.rs @@ -5,7 +5,7 @@ use k_ap::{ActorBlocklist, BlockedDomain, DomainBlocklist}; use sqlx::Row; use super::SqliteFederationRepository; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl DomainBlocklist for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-federation/src/follow/followers.rs b/crates/adapters/sqlite-federation/src/follow/followers.rs index 598ff9d9..459bcf60 100644 --- a/crates/adapters/sqlite-federation/src/follow/followers.rs +++ b/crates/adapters/sqlite-federation/src/follow/followers.rs @@ -5,7 +5,7 @@ use k_ap::{Follower, FollowerReader, FollowerStatus, FollowerWriter, RemoteActor use sqlx::Row; use crate::{SqliteFederationRepository, remote_actor_from_row, status_to_str, str_to_status}; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl FollowerWriter for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-federation/src/follow/following.rs b/crates/adapters/sqlite-federation/src/follow/following.rs index 2b69e348..e22575f2 100644 --- a/crates/adapters/sqlite-federation/src/follow/following.rs +++ b/crates/adapters/sqlite-federation/src/follow/following.rs @@ -4,7 +4,7 @@ use chrono::Utc; use k_ap::{FollowingReader, FollowingStatus, FollowingWriter, RemoteActor, RemoteActorCache}; use crate::{SqliteFederationRepository, remote_actor_from_row}; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl FollowingWriter for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-federation/src/lib.rs b/crates/adapters/sqlite-federation/src/lib.rs index 84a2aab1..32e6a9c4 100644 --- a/crates/adapters/sqlite-federation/src/lib.rs +++ b/crates/adapters/sqlite-federation/src/lib.rs @@ -79,7 +79,7 @@ pub fn wire( instance: domain::value_objects::InstanceIdentity, ) -> activitypub::FederationRepos { let fed = std::sync::Arc::new(SqliteFederationRepository::new(pool.clone())); - let social = std::sync::Arc::new(sqlite_social::SqliteSocialRepository::new(pool, instance)); + let social = std::sync::Arc::new(sqlite::SqliteSocialRepository::new(pool, instance)); activitypub::FederationRepos { activity: std::sync::Arc::clone(&fed) as _, follow: std::sync::Arc::clone(&fed) as _, diff --git a/crates/adapters/sqlite-federation/src/review.rs b/crates/adapters/sqlite-federation/src/review.rs index ebbfd300..c648c684 100644 --- a/crates/adapters/sqlite-federation/src/review.rs +++ b/crates/adapters/sqlite-federation/src/review.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use domain::models::{Review, ReviewSource}; use super::SqliteFederationRepository; -use adapter_common::datetime_to_str; +use sqlite::persistence::datetime_to_str; #[async_trait] impl RemoteReviewRepository for SqliteFederationRepository { diff --git a/crates/adapters/sqlite-search/Cargo.toml b/crates/adapters/sqlite-search/Cargo.toml deleted file mode 100644 index b6da39d2..00000000 --- a/crates/adapters/sqlite-search/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "sqlite-search" -version = "0.1.0" -edition = "2021" - -[dependencies] -domain = { workspace = true } -adapter-common = { workspace = true } -async-trait = { workspace = true } -sqlx = { workspace = true } -uuid = { workspace = true } - -[dev-dependencies] -tokio = { workspace = true } diff --git a/crates/adapters/sqlite-social/Cargo.toml b/crates/adapters/sqlite-social/Cargo.toml deleted file mode 100644 index 2fd4adf0..00000000 --- a/crates/adapters/sqlite-social/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "sqlite-social" -version = "0.1.0" -edition.workspace = true - -[dependencies] -sqlx = { workspace = true } -adapter-common = { workspace = true } -domain = { workspace = true } -uuid = { workspace = true } -chrono = { workspace = true } -async-trait = { workspace = true } - -[dev-dependencies] -tokio = { workspace = true } diff --git a/crates/adapters/sqlite/Cargo.toml b/crates/adapters/sqlite/Cargo.toml index d46f49c5..4f207f4d 100644 --- a/crates/adapters/sqlite/Cargo.toml +++ b/crates/adapters/sqlite/Cargo.toml @@ -4,11 +4,10 @@ version = "0.1.0" edition.workspace = true [dependencies] -sqlx = { workspace = true, features = ["macros"] } +sqlx = { workspace = true, features = ["macros", "chrono"] } -adapter-common = { workspace = true } domain = { workspace = true } -sqlite-social = { workspace = true } +event-payload = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } anyhow = { workspace = true } @@ -22,5 +21,4 @@ bytes = { workspace = true } async-stream = { workspace = true } [dev-dependencies] -sqlite-event-queue = { workspace = true } tempfile = { workspace = true } diff --git a/crates/adapters/sqlite-event-queue/migrations/0100_event_queue.sql b/crates/adapters/sqlite/migrations/0100_event_queue.sql similarity index 100% rename from crates/adapters/sqlite-event-queue/migrations/0100_event_queue.sql rename to crates/adapters/sqlite/migrations/0100_event_queue.sql diff --git a/crates/adapters/sqlite/src/diary.rs b/crates/adapters/sqlite/src/diary.rs index 26788b96..0ca6bb62 100644 --- a/crates/adapters/sqlite/src/diary.rs +++ b/crates/adapters/sqlite/src/diary.rs @@ -27,13 +27,13 @@ impl SqliteDiaryRepository { None => sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM reviews") .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error), + .map_err(crate::shared::map_sqlx_error), Some(id) => { sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM reviews WHERE movie_id = ?") .bind(id) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } } } @@ -64,7 +64,7 @@ impl SqliteDiaryRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn fetch_movie_diary_rows( @@ -96,7 +96,7 @@ impl SqliteDiaryRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn count_user_diary_entries( @@ -127,7 +127,7 @@ impl SqliteDiaryRepository { } q.fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn fetch_user_diary_rows( @@ -173,7 +173,7 @@ impl SqliteDiaryRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } } @@ -340,7 +340,7 @@ impl DiaryQuery for SqliteDiaryRepository { let total = count_q .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let rows_q = bind_filter_params!(sqlx::query_as::<_, FeedRow>(&select_sql)); let rows = rows_q @@ -348,7 +348,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let items = rows .into_iter() @@ -373,7 +373,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(&id_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .ok_or_else(|| DomainError::NotFound(format!("Movie {}", id_str)))? .into_domain()?; @@ -384,7 +384,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(&id_str) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(ReviewRow::into_domain) .collect::, _>>()?; @@ -405,7 +405,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.into_iter().map(DiaryRow::into_domain).collect() } @@ -430,7 +430,7 @@ impl DiaryQuery for SqliteDiaryRepository { while let Some(row) = futures::StreamExt::next(&mut rows).await { yield match row { Ok(r) => r.into_domain(), - Err(e) => Err(adapter_common::map_sqlx_error(e)), + Err(e) => Err(crate::shared::map_sqlx_error(e)), }; } }) @@ -453,7 +453,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(id_str) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) .map(MovieStatsRow::into_domain) } @@ -471,7 +471,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(&id_str) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let rows = sqlx::query_as::<_, FeedRow>( "SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path, @@ -492,7 +492,7 @@ impl DiaryQuery for SqliteDiaryRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let items = rows .into_iter() @@ -512,7 +512,7 @@ impl DiaryQuery for SqliteDiaryRepository { sqlx::query_scalar("SELECT COUNT(*) FROM reviews WHERE remote_actor_url IS NULL") .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(count as u64) } } diff --git a/crates/adapters/sqlite-event-queue/src/lib.rs b/crates/adapters/sqlite/src/event_queue/mod.rs similarity index 99% rename from crates/adapters/sqlite-event-queue/src/lib.rs rename to crates/adapters/sqlite/src/event_queue/mod.rs index 5cb3cfd7..7798d060 100644 --- a/crates/adapters/sqlite-event-queue/src/lib.rs +++ b/crates/adapters/sqlite/src/event_queue/mod.rs @@ -1,4 +1,3 @@ -mod migrations; mod payload; use std::sync::Arc; @@ -49,7 +48,6 @@ pub struct SqliteEventQueue { impl SqliteEventQueue { pub async fn create(pool: SqlitePool, config: DbEventQueueConfig) -> anyhow::Result { - migrations::run(&pool).await?; Ok(Self { pool, config: Arc::new(config), diff --git a/crates/adapters/sqlite-event-queue/src/payload.rs b/crates/adapters/sqlite/src/event_queue/payload.rs similarity index 100% rename from crates/adapters/sqlite-event-queue/src/payload.rs rename to crates/adapters/sqlite/src/event_queue/payload.rs diff --git a/crates/adapters/sqlite/src/goals.rs b/crates/adapters/sqlite/src/goals.rs index 8ceff8e5..a8934cae 100644 --- a/crates/adapters/sqlite/src/goals.rs +++ b/crates/adapters/sqlite/src/goals.rs @@ -39,7 +39,7 @@ impl GoalCommand for SqliteGoalRepository { .bind(&created_at) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -53,7 +53,7 @@ impl GoalCommand for SqliteGoalRepository { .bind(&id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if result.rows_affected() == 0 { return Err(DomainError::NotFound("Goal not found".into())); @@ -70,7 +70,7 @@ impl GoalCommand for SqliteGoalRepository { .bind(&uid) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if result.rows_affected() == 0 { return Err(DomainError::NotFound("Goal not found".into())); @@ -97,7 +97,7 @@ impl GoalQuery for SqliteGoalRepository { .bind(y) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.map(|r| row_to_goal(&r)).transpose() } @@ -112,7 +112,7 @@ impl GoalQuery for SqliteGoalRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_goal).collect() } diff --git a/crates/adapters/sqlite/src/import_profile.rs b/crates/adapters/sqlite/src/import_profile.rs index 535f01cd..86bf680d 100644 --- a/crates/adapters/sqlite/src/import_profile.rs +++ b/crates/adapters/sqlite/src/import_profile.rs @@ -125,7 +125,7 @@ impl ImportProfileRepository for SqliteImportProfileRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn list_for_user(&self, user_id: &UserId) -> Result, DomainError> { @@ -136,7 +136,7 @@ impl ImportProfileRepository for SqliteImportProfileRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter() .map(|r| { @@ -178,7 +178,7 @@ impl ImportProfileRepository for SqliteImportProfileRepository { .bind(&uid_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.map(|r| { use sqlx::Row; @@ -210,6 +210,6 @@ impl ImportProfileRepository for SqliteImportProfileRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } } diff --git a/crates/adapters/sqlite/src/import_session.rs b/crates/adapters/sqlite/src/import_session.rs index f978ece3..fd58a00a 100644 --- a/crates/adapters/sqlite/src/import_session.rs +++ b/crates/adapters/sqlite/src/import_session.rs @@ -311,7 +311,7 @@ impl ImportSessionRepository for SqliteImportSessionRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn get( @@ -329,7 +329,7 @@ impl ImportSessionRepository for SqliteImportSessionRepository { .bind(&uid_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.map(|r| { use sqlx::Row; @@ -356,7 +356,7 @@ impl ImportSessionRepository for SqliteImportSessionRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn delete(&self, id: &ImportSessionId) -> Result<(), DomainError> { @@ -366,14 +366,14 @@ impl ImportSessionRepository for SqliteImportSessionRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn delete_expired(&self) -> Result { let result = sqlx::query("DELETE FROM import_sessions WHERE expires_at < datetime('now')") .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected()) } @@ -386,6 +386,6 @@ impl ImportSessionRepository for SqliteImportSessionRepository { .execute(&self.pool) .await .map(|_| ()) - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } } diff --git a/crates/adapters/sqlite/src/insights.rs b/crates/adapters/sqlite/src/insights.rs index 2224901f..752a7153 100644 --- a/crates/adapters/sqlite/src/insights.rs +++ b/crates/adapters/sqlite/src/insights.rs @@ -6,7 +6,7 @@ use domain::{ }; use sqlx::{Row, SqlitePool}; -use adapter_common::{parse_datetime, parse_uuid}; +use crate::shared::{parse_datetime, parse_uuid}; /// SQLite read side of Insights (ADR-0010). Deliberately thin: one query for /// review basics, one for genres — every threshold and comparison lives in @@ -33,7 +33,7 @@ impl InsightsQuery for SqliteInsightsQuery { .bind(user_id.value().to_string()) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; // Subquery rather than an `IN (?, …)` bind list: a whole diary can // exceed SQLite's bound-parameter limit. @@ -48,16 +48,14 @@ impl InsightsQuery for SqliteInsightsQuery { .bind(user_id.value().to_string()) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let mut genres_map: HashMap> = HashMap::new(); for row in genre_rows { let mid: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; - let name: String = row - .try_get("name") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; + let name: String = row.try_get("name").map_err(crate::shared::map_sqlx_error)?; genres_map.entry(mid).or_default().push(name); } @@ -65,16 +63,16 @@ impl InsightsQuery for SqliteInsightsQuery { for row in &rows { let movie_id: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let rating: i64 = row .try_get("rating") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let watched_at: String = row .try_get("watched_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let watch_medium: Option = row .try_get("watch_medium") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; result.push(WatchRow { movie_id: parse_uuid(&movie_id)?, diff --git a/crates/adapters/sqlite/src/lib.rs b/crates/adapters/sqlite/src/lib.rs index 05a59f60..87589544 100644 --- a/crates/adapters/sqlite/src/lib.rs +++ b/crates/adapters/sqlite/src/lib.rs @@ -1,6 +1,7 @@ use sqlx::SqlitePool; mod diary; +mod event_queue; mod goals; mod image_ref; mod import_profile; @@ -15,6 +16,9 @@ mod profile; mod profile_fields; mod refresh_sessions; mod review; +mod search; +mod shared; +mod social; mod stats; mod user_settings; mod users; @@ -23,6 +27,7 @@ mod watchlist; mod wrapup; pub use diary::SqliteDiaryRepository; +pub use event_queue::{DbEventQueueConfig, SqliteEventQueue}; pub use image_ref::{SqliteImageRefAdapter, create_image_ref}; pub use import_profile::SqliteImportProfileRepository; pub use import_session::SqliteImportSessionRepository; @@ -34,13 +39,23 @@ pub use profile::SqliteMovieProfileRepository; pub use profile_fields::SqliteProfileFieldsRepository; pub use refresh_sessions::SqliteRefreshSessionAdapter; pub use review::SqliteReviewRepository; -pub use sqlite_social::SqliteApContentQuery; +pub use search::create_search_adapter; +pub use social::{ + SqliteApContentQuery, SqliteRemoteGoalRepository, SqliteSocialRepository, + create_federated_profile_query, +}; pub use stats::SqliteStatsRepository; pub use users::SqliteUserRepository; pub use watch_event::{SqliteWatchEventRepository, SqliteWebhookTokenRepository}; pub use watchlist::SqliteWatchlistRepository; pub use wrapup::{SqliteWrapUpRepository, SqliteWrapUpStatsQuery}; +/// Row helpers shared with the `sqlite-federation` crate (which cannot live +/// here because it depends on `activitypub`/`k-ap`). +pub mod persistence { + pub use crate::shared::datetime_to_str; +} + pub fn create_profile_fields_repo( pool: sqlx::SqlitePool, ) -> std::sync::Arc { @@ -122,9 +137,7 @@ pub async fn wire(database_url: &str) -> anyhow::Result { goal_query: std::sync::Arc::new(goals::SqliteGoalRepository::new(pool.clone())) as _, user_settings: std::sync::Arc::clone(&user_settings_repo) as _, federation_settings: user_settings_repo as _, - remote_goal: std::sync::Arc::new(sqlite_social::SqliteRemoteGoalRepository::new( - pool.clone(), - )) as _, + remote_goal: std::sync::Arc::new(SqliteRemoteGoalRepository::new(pool.clone())) as _, deduplicator: std::sync::Arc::new(SqliteMovieDeduplicator::new(pool)) as _, }) } diff --git a/crates/adapters/sqlite/src/models.rs b/crates/adapters/sqlite/src/models.rs index e4b8a5da..250a26da 100644 --- a/crates/adapters/sqlite/src/models.rs +++ b/crates/adapters/sqlite/src/models.rs @@ -1,4 +1,4 @@ -use adapter_common::{ +use crate::shared::{ movie_row_to_domain, movie_stats_to_domain, movie_summary_to_domain, review_row_to_domain, user_summary_to_domain, watchlist_entry_to_domain, watchlist_with_movie_to_domain, }; diff --git a/crates/adapters/sqlite/src/movie.rs b/crates/adapters/sqlite/src/movie.rs index 84f2352b..e60029e6 100644 --- a/crates/adapters/sqlite/src/movie.rs +++ b/crates/adapters/sqlite/src/movie.rs @@ -50,7 +50,7 @@ impl MovieCommand for SqliteMovieRepository { .bind(&poster_path) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -61,7 +61,7 @@ impl MovieCommand for SqliteMovieRepository { .bind(&id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } } @@ -80,7 +80,7 @@ impl MovieQuery for SqliteMovieRepository { .bind(id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .map(MovieRow::into_domain) .transpose() } @@ -94,7 +94,7 @@ impl MovieQuery for SqliteMovieRepository { .bind(&id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .map(MovieRow::into_domain) .transpose() } @@ -114,7 +114,7 @@ impl MovieQuery for SqliteMovieRepository { .bind(y) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(MovieRow::into_domain) .collect() @@ -139,7 +139,7 @@ impl MovieQuery for SqliteMovieRepository { let rows = q .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows.into_iter().collect()) } @@ -166,7 +166,7 @@ impl MovieQuery for SqliteMovieRepository { let rows = q .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows .into_iter() .map(|r| { @@ -218,7 +218,7 @@ impl MovieQuery for SqliteMovieRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let total: i64 = sqlx::query( "SELECT COUNT(DISTINCT m.id) \ @@ -236,7 +236,7 @@ impl MovieQuery for SqliteMovieRepository { .bind(genre) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .try_get(0) .unwrap_or(0); @@ -260,7 +260,7 @@ impl MovieQuery for SqliteMovieRepository { ) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(MovieRow::into_domain) .collect() diff --git a/crates/adapters/sqlite/src/movie_dedup.rs b/crates/adapters/sqlite/src/movie_dedup.rs index 689ca920..32440e3b 100644 --- a/crates/adapters/sqlite/src/movie_dedup.rs +++ b/crates/adapters/sqlite/src/movie_dedup.rs @@ -35,7 +35,7 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .pool .begin() .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT INTO movies (id, external_metadata_id, title, release_year, director, poster_path) @@ -45,14 +45,14 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { poster_path = COALESCE(excluded.poster_path, movies.poster_path)", ) .bind(&new).bind(&ext_id).bind(&title).bind(year).bind(&director).bind(&poster) - .execute(&mut *tx).await.map_err(adapter_common::map_sqlx_error)?; + .execute(&mut *tx).await.map_err(crate::shared::map_sqlx_error)?; let reviews = sqlx::query("UPDATE reviews SET movie_id = ? WHERE movie_id = ?") .bind(&new) .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .rows_affected(); let watchlist = sqlx::query("UPDATE watchlist_entries SET movie_id = ? WHERE movie_id = ?") @@ -60,7 +60,7 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .rows_affected(); let watch_events = sqlx::query("UPDATE watch_events SET movie_id = ? WHERE movie_id = ?") @@ -68,7 +68,7 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .rows_affected(); let profiles = sqlx::query("UPDATE movie_profiles SET movie_id = ? WHERE movie_id = ?") @@ -76,7 +76,7 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .rows_affected(); sqlx::query( @@ -87,12 +87,12 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movie_genres WHERE movie_id = ?") .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT OR IGNORE INTO movie_keywords (movie_id, tmdb_id, name) @@ -102,40 +102,40 @@ impl MovieDeduplicator for SqliteMovieDeduplicator { .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movie_keywords WHERE movie_id = ?") .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT OR IGNORE INTO movie_cast (movie_id, tmdb_person_id, name, character, billing_order, profile_path) SELECT ?, tmdb_person_id, name, character, billing_order, profile_path FROM movie_cast WHERE movie_id = ?", - ).bind(&new).bind(&old).execute(&mut *tx).await.map_err(adapter_common::map_sqlx_error)?; + ).bind(&new).bind(&old).execute(&mut *tx).await.map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movie_cast WHERE movie_id = ?") .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT OR IGNORE INTO movie_crew (movie_id, tmdb_person_id, name, job, department, profile_path) SELECT ?, tmdb_person_id, name, job, department, profile_path FROM movie_crew WHERE movie_id = ?", - ).bind(&new).bind(&old).execute(&mut *tx).await.map_err(adapter_common::map_sqlx_error)?; + ).bind(&new).bind(&old).execute(&mut *tx).await.map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movie_crew WHERE movie_id = ?") .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movies WHERE id = ?") .bind(&old) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; - tx.commit().await.map_err(adapter_common::map_sqlx_error)?; + tx.commit().await.map_err(crate::shared::map_sqlx_error)?; Ok(reviews + watchlist + watch_events + profiles) } diff --git a/crates/adapters/sqlite/src/persons.rs b/crates/adapters/sqlite/src/persons.rs index e4cf30c3..110e2e45 100644 --- a/crates/adapters/sqlite/src/persons.rs +++ b/crates/adapters/sqlite/src/persons.rs @@ -52,7 +52,7 @@ impl PersonCommand for SqlitePersonAdapter { .bind(person.profile_path()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } Ok(()) } @@ -85,7 +85,7 @@ impl PersonCommand for SqlitePersonAdapter { .bind(batch_size) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let has_more = rows.len() as u32 >= batch_size; let mut count = 0u64; @@ -105,7 +105,7 @@ impl PersonCommand for SqlitePersonAdapter { .bind(&row.profile_path) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; count += 1; } Ok((count, has_more)) @@ -133,7 +133,7 @@ impl PersonCommand for SqlitePersonAdapter { .bind(id.value().to_string()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } } @@ -147,7 +147,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(id.value().to_string()) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(row.map(PersonRow::into_person)) } @@ -162,7 +162,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(id.value()) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(row.map(PersonRow::into_person)) } @@ -178,7 +178,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(id.value().to_string()) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .flatten(); let Some(tmdb_id) = tmdb_id else { @@ -199,7 +199,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(tmdb_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| CastCredit { movie_id: MovieId::from_uuid(uuid::Uuid::parse_str(&r.id).unwrap_or_default()), @@ -220,7 +220,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(tmdb_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| CrewCredit { movie_id: MovieId::from_uuid(uuid::Uuid::parse_str(&r.id).unwrap_or_default()), @@ -243,7 +243,7 @@ impl PersonQuery for SqlitePersonAdapter { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows.into_iter().map(PersonRow::into_person).collect()) } @@ -261,7 +261,7 @@ impl PersonQuery for SqlitePersonAdapter { ) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows .into_iter() diff --git a/crates/adapters/sqlite/src/profile.rs b/crates/adapters/sqlite/src/profile.rs index f6437efa..e518d3ef 100644 --- a/crates/adapters/sqlite/src/profile.rs +++ b/crates/adapters/sqlite/src/profile.rs @@ -28,7 +28,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .pool .begin() .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( r#"INSERT INTO movie_profiles @@ -61,13 +61,13 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&enriched_at) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query("DELETE FROM movie_genres WHERE movie_id = ?") .bind(&movie_id) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; for g in &p.genres { sqlx::query( "INSERT OR IGNORE INTO movie_genres (movie_id, tmdb_id, name) VALUES (?,?,?)", @@ -77,14 +77,14 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&g.name) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } sqlx::query("DELETE FROM movie_keywords WHERE movie_id = ?") .bind(&movie_id) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; for k in &p.keywords { sqlx::query( "INSERT OR IGNORE INTO movie_keywords (movie_id, tmdb_id, name) VALUES (?,?,?)", @@ -94,14 +94,14 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&k.name) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } sqlx::query("DELETE FROM movie_cast WHERE movie_id = ?") .bind(&movie_id) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; for c in &p.cast { sqlx::query( "INSERT OR IGNORE INTO movie_cast \ @@ -116,14 +116,14 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&c.profile_path) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } sqlx::query("DELETE FROM movie_crew WHERE movie_id = ?") .bind(&movie_id) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; for cr in &p.crew { sqlx::query( "INSERT OR IGNORE INTO movie_crew \ @@ -138,10 +138,10 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&cr.profile_path) .execute(&mut *tx) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } - tx.commit().await.map_err(adapter_common::map_sqlx_error) + tx.commit().await.map_err(crate::shared::map_sqlx_error) } async fn get_by_movie_id(&self, id: &MovieId) -> Result, DomainError> { @@ -156,7 +156,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&movie_id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let row = match row { Some(r) => r, @@ -174,7 +174,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&movie_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| Genre { tmdb_id: r.try_get::("tmdb_id").unwrap_or(0) as u32, @@ -186,7 +186,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&movie_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| Keyword { tmdb_id: r.try_get::("tmdb_id").unwrap_or(0) as u32, @@ -201,7 +201,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&movie_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| CastMember { tmdb_person_id: r.try_get::("tmdb_person_id").unwrap_or(0) as u64, @@ -222,7 +222,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&movie_id) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(|r| CrewMember { tmdb_person_id: r.try_get::("tmdb_person_id").unwrap_or(0) as u64, @@ -284,7 +284,7 @@ impl MovieProfileRepository for SqliteMovieProfileRepository { .bind(&threshold) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows .into_iter() diff --git a/crates/adapters/sqlite/src/profile_fields.rs b/crates/adapters/sqlite/src/profile_fields.rs index 6d5ce907..9f11241f 100644 --- a/crates/adapters/sqlite/src/profile_fields.rs +++ b/crates/adapters/sqlite/src/profile_fields.rs @@ -26,7 +26,7 @@ impl UserProfileFieldsRepository for SqliteProfileFieldsRepository { .bind(&id_str) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(rows .iter() @@ -48,7 +48,7 @@ impl UserProfileFieldsRepository for SqliteProfileFieldsRepository { .bind(&id_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; for (i, field) in fields.into_iter().enumerate() { let id = uuid::Uuid::new_v4().to_string(); @@ -63,7 +63,7 @@ impl UserProfileFieldsRepository for SqliteProfileFieldsRepository { .bind(position) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } Ok(()) diff --git a/crates/adapters/sqlite/src/refresh_sessions.rs b/crates/adapters/sqlite/src/refresh_sessions.rs index c2124ebd..27ac5790 100644 --- a/crates/adapters/sqlite/src/refresh_sessions.rs +++ b/crates/adapters/sqlite/src/refresh_sessions.rs @@ -30,7 +30,7 @@ impl RefreshSessionRepository for SqliteRefreshSessionAdapter { .bind(session.created_at.to_rfc3339()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -41,7 +41,7 @@ impl RefreshSessionRepository for SqliteRefreshSessionAdapter { .bind(token) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.map(RefreshSessionRow::into_domain).transpose() } @@ -51,7 +51,7 @@ impl RefreshSessionRepository for SqliteRefreshSessionAdapter { .bind(token) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -60,7 +60,7 @@ impl RefreshSessionRepository for SqliteRefreshSessionAdapter { .bind(user_id.value().to_string()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -70,7 +70,7 @@ impl RefreshSessionRepository for SqliteRefreshSessionAdapter { .bind(&now) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected()) } } diff --git a/crates/adapters/sqlite/src/review.rs b/crates/adapters/sqlite/src/review.rs index 4768a496..9fc2c6b5 100644 --- a/crates/adapters/sqlite/src/review.rs +++ b/crates/adapters/sqlite/src/review.rs @@ -8,7 +8,7 @@ use domain::{ use sqlx::SqlitePool; use crate::models::ReviewRow; -use adapter_common::datetime_to_str; +use crate::shared::datetime_to_str; pub struct SqliteReviewRepository { pool: SqlitePool, @@ -51,7 +51,7 @@ impl ReviewRepository for SqliteReviewRepository { .bind(review.spoilers()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -65,7 +65,7 @@ impl ReviewRepository for SqliteReviewRepository { .bind(&id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .map(ReviewRow::into_domain) .transpose() } @@ -88,7 +88,7 @@ impl ReviewRepository for SqliteReviewRepository { .bind(&id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -99,7 +99,7 @@ impl ReviewRepository for SqliteReviewRepository { .bind(&id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -112,7 +112,7 @@ impl ReviewRepository for SqliteReviewRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(ReviewRow::into_domain) .collect() diff --git a/crates/adapters/sqlite-search/src/lib.rs b/crates/adapters/sqlite/src/search.rs similarity index 93% rename from crates/adapters/sqlite-search/src/lib.rs rename to crates/adapters/sqlite/src/search.rs index 36e95e5d..528f5520 100644 --- a/crates/adapters/sqlite-search/src/lib.rs +++ b/crates/adapters/sqlite/src/search.rs @@ -5,8 +5,8 @@ use domain::{ errors::DomainError, models::PersonId, models::{ - collections::Paginated, EntityType, IndexableDocument, MovieSearchHit, PersonSearchHit, - SearchQuery, SearchResults, + EntityType, IndexableDocument, MovieSearchHit, PersonSearchHit, SearchQuery, SearchResults, + collections::Paginated, }, ports::{SearchCommand, SearchPort}, value_objects::MovieId, @@ -82,7 +82,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(&movie_id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT INTO movies_fts(movie_id, title, director, overview, genres, keywords, cast_names, crew_names, release_year, language) @@ -100,7 +100,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(&language) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -114,7 +114,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(&person_id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; sqlx::query( "INSERT INTO people_fts(person_id, name, known_for_department) VALUES (?, ?, ?)", @@ -124,7 +124,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(person.known_for_department()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -140,7 +140,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } EntityType::Person => { sqlx::query( @@ -149,7 +149,7 @@ impl SearchCommand for SqliteSearchAdapter { .bind(id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; } } Ok(()) @@ -201,7 +201,7 @@ impl SqliteSearchAdapter { .bind(query.filters.year.map(|y| y as i64)) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; count as u64 } else { let count: i64 = sqlx::query_scalar( @@ -217,7 +217,7 @@ impl SqliteSearchAdapter { .bind(query.filters.year.map(|y| y as i64)) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; count as u64 }; @@ -245,7 +245,7 @@ impl SqliteSearchAdapter { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? } else { sqlx::query_as::<_, Row>( "SELECT m.id, m.title, m.release_year, m.director, m.poster_path, @@ -266,7 +266,7 @@ impl SqliteSearchAdapter { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? }; let items = rows .into_iter() @@ -317,7 +317,7 @@ impl SqliteSearchAdapter { .bind(&fts_query) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; count as u64 }; @@ -342,7 +342,7 @@ impl SqliteSearchAdapter { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let mut items = Vec::with_capacity(rows.len()); for row in rows { @@ -351,7 +351,7 @@ impl SqliteSearchAdapter { .bind(&row.person_id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .flatten(); let known_for_titles = if let Some(tid) = tmdb_id { @@ -391,5 +391,4 @@ impl SqliteSearchAdapter { } #[cfg(test)] -#[path = "tests/lib.rs"] mod tests; diff --git a/crates/adapters/sqlite-search/src/tests/lib.rs b/crates/adapters/sqlite/src/search/tests.rs similarity index 98% rename from crates/adapters/sqlite-search/src/tests/lib.rs rename to crates/adapters/sqlite/src/search/tests.rs index 25771dc9..80f0faf6 100644 --- a/crates/adapters/sqlite-search/src/tests/lib.rs +++ b/crates/adapters/sqlite/src/search/tests.rs @@ -1,7 +1,7 @@ use super::create_search_adapter; use domain::{ models::{ - collections::PageParams, EntityType, IndexableDocument, Movie, SearchFilters, SearchQuery, + EntityType, IndexableDocument, Movie, SearchFilters, SearchQuery, collections::PageParams, }, value_objects::{MovieId, MovieTitle, ReleaseYear}, }; diff --git a/crates/adapters/adapter-common/src/lib.rs b/crates/adapters/sqlite/src/shared.rs similarity index 89% rename from crates/adapters/adapter-common/src/lib.rs rename to crates/adapters/sqlite/src/shared.rs index f0b75266..13ae4078 100644 --- a/crates/adapters/adapter-common/src/lib.rs +++ b/crates/adapters/sqlite/src/shared.rs @@ -10,17 +10,17 @@ use domain::{ }, }; -pub fn map_sqlx_error(e: sqlx::Error) -> DomainError { +pub(crate) fn map_sqlx_error(e: sqlx::Error) -> DomainError { tracing::error!("Database error: {:?}", e); DomainError::InfrastructureError("Database operation failed".into()) } -pub fn parse_uuid(s: &str) -> Result { +pub(crate) fn parse_uuid(s: &str) -> Result { uuid::Uuid::parse_str(s) .map_err(|e| DomainError::InfrastructureError(format!("Invalid UUID '{}': {}", s, e))) } -pub fn parse_datetime(s: &str) -> Result { +pub(crate) fn parse_datetime(s: &str) -> Result { chrono::NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S") .map_err(|e| DomainError::InfrastructureError(format!("Invalid datetime '{}': {}", s, e))) } @@ -29,7 +29,7 @@ pub fn datetime_to_str(dt: &chrono::NaiveDateTime) -> String { dt.format("%Y-%m-%d %H:%M:%S").to_string() } -pub fn format_year_month(ym: &str) -> String { +pub(crate) fn format_year_month(ym: &str) -> String { let parts: Vec<&str> = ym.splitn(2, '-').collect(); if parts.len() != 2 { return ym.to_string(); @@ -53,7 +53,7 @@ pub fn format_year_month(ym: &str) -> String { format!("{} '{}", month, year) } -pub fn movie_row_to_domain( +pub(crate) fn movie_row_to_domain( id: String, external_metadata_id: Option, title: String, @@ -79,7 +79,7 @@ pub fn movie_row_to_domain( } #[allow(clippy::too_many_arguments)] -pub fn review_row_to_domain( +pub(crate) fn review_row_to_domain( id: String, movie_id: String, user_id: String, @@ -117,7 +117,7 @@ pub fn review_row_to_domain( })) } -pub fn movie_summary_to_domain( +pub(crate) fn movie_summary_to_domain( movie: Movie, genres: Vec, runtime_minutes: Option, @@ -135,7 +135,7 @@ pub fn movie_summary_to_domain( } } -pub fn movie_stats_to_domain( +pub(crate) fn movie_stats_to_domain( total_count: i64, avg_rating: Option, federated_count: i64, @@ -156,7 +156,7 @@ pub fn movie_stats_to_domain( } #[allow(clippy::too_many_arguments)] -pub fn user_summary_to_domain( +pub(crate) fn user_summary_to_domain( id: String, email: String, username: String, @@ -176,7 +176,7 @@ pub fn user_summary_to_domain( )) } -pub fn watchlist_entry_to_domain( +pub(crate) fn watchlist_entry_to_domain( id: String, user_id: String, movie_id: String, @@ -190,6 +190,9 @@ pub fn watchlist_entry_to_domain( }) } -pub fn watchlist_with_movie_to_domain(entry: WatchlistEntry, movie: Movie) -> WatchlistWithMovie { +pub(crate) fn watchlist_with_movie_to_domain( + entry: WatchlistEntry, + movie: Movie, +) -> WatchlistWithMovie { WatchlistWithMovie { entry, movie } } diff --git a/crates/adapters/sqlite-social/src/ap_content.rs b/crates/adapters/sqlite/src/social/ap_content.rs similarity index 97% rename from crates/adapters/sqlite-social/src/ap_content.rs rename to crates/adapters/sqlite/src/social/ap_content.rs index aeb412f9..b441b467 100644 --- a/crates/adapters/sqlite-social/src/ap_content.rs +++ b/crates/adapters/sqlite/src/social/ap_content.rs @@ -25,7 +25,7 @@ impl SqliteApContentQuery { // ── Local row types ────────────────────────────────────────────────────────── -use adapter_common::{parse_datetime, parse_uuid}; +use crate::shared::{parse_datetime, parse_uuid}; #[derive(sqlx::FromRow)] struct MovieRow { @@ -205,7 +205,7 @@ impl LocalApContentQuery for SqliteApContentQuery { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.into_iter().map(WatchlistRow::into_domain).collect() } @@ -225,7 +225,7 @@ impl LocalApContentQuery for SqliteApContentQuery { .bind(&mid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.into_iter().map(DiaryRow::into_domain).collect() } @@ -254,7 +254,7 @@ impl LocalApContentQuery for SqliteApContentQuery { .bind(limit_i64) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? } else { sqlx::query_as::<_, DiaryRow>( "SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path, @@ -269,7 +269,7 @@ impl LocalApContentQuery for SqliteApContentQuery { .bind(limit_i64) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? }; rows.into_iter().map(DiaryRow::into_domain).collect() } diff --git a/crates/adapters/sqlite-social/src/federated_profile.rs b/crates/adapters/sqlite/src/social/federated_profile.rs similarity index 100% rename from crates/adapters/sqlite-social/src/federated_profile.rs rename to crates/adapters/sqlite/src/social/federated_profile.rs diff --git a/crates/adapters/sqlite-social/src/follow_repository.rs b/crates/adapters/sqlite/src/social/follow_repository.rs similarity index 99% rename from crates/adapters/sqlite-social/src/follow_repository.rs rename to crates/adapters/sqlite/src/social/follow_repository.rs index 51dde13d..506c9c7c 100644 --- a/crates/adapters/sqlite-social/src/follow_repository.rs +++ b/crates/adapters/sqlite/src/social/follow_repository.rs @@ -7,7 +7,7 @@ use domain::{ use sqlx::Row; use crate::SqliteSocialRepository; -use adapter_common::datetime_to_str; +use crate::shared::datetime_to_str; fn follow_status_to_str(status: &FollowStatus) -> &'static str { match status { diff --git a/crates/adapters/sqlite-social/src/social.rs b/crates/adapters/sqlite/src/social/local_social.rs similarity index 100% rename from crates/adapters/sqlite-social/src/social.rs rename to crates/adapters/sqlite/src/social/local_social.rs diff --git a/crates/adapters/sqlite-social/src/lib.rs b/crates/adapters/sqlite/src/social/mod.rs similarity index 97% rename from crates/adapters/sqlite-social/src/lib.rs rename to crates/adapters/sqlite/src/social/mod.rs index 06f3e466..1f447813 100644 --- a/crates/adapters/sqlite-social/src/lib.rs +++ b/crates/adapters/sqlite/src/social/mod.rs @@ -1,6 +1,6 @@ mod federated_profile; mod follow_repository; -mod social; +mod local_social; mod watchlist; pub mod ap_content; diff --git a/crates/adapters/sqlite-social/src/remote_goals.rs b/crates/adapters/sqlite/src/social/remote_goals.rs similarity index 92% rename from crates/adapters/sqlite-social/src/remote_goals.rs rename to crates/adapters/sqlite/src/social/remote_goals.rs index 73252009..cfc2fc22 100644 --- a/crates/adapters/sqlite-social/src/remote_goals.rs +++ b/crates/adapters/sqlite/src/social/remote_goals.rs @@ -31,7 +31,7 @@ impl RemoteGoalRepository for SqliteRemoteGoalRepository { .bind(&received) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -48,7 +48,7 @@ impl RemoteGoalRepository for SqliteRemoteGoalRepository { .bind(ap_id) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -59,7 +59,7 @@ impl RemoteGoalRepository for SqliteRemoteGoalRepository { .bind(actor_url) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -69,7 +69,7 @@ impl RemoteGoalRepository for SqliteRemoteGoalRepository { .bind(actor_url) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -82,7 +82,7 @@ impl RemoteGoalRepository for SqliteRemoteGoalRepository { .bind(actor_url) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter() .map(|r| { diff --git a/crates/adapters/sqlite-social/src/tests/follow_relation_tests.rs b/crates/adapters/sqlite/src/social/tests/follow_relation_tests.rs similarity index 100% rename from crates/adapters/sqlite-social/src/tests/follow_relation_tests.rs rename to crates/adapters/sqlite/src/social/tests/follow_relation_tests.rs diff --git a/crates/adapters/sqlite-social/src/watchlist.rs b/crates/adapters/sqlite/src/social/watchlist.rs similarity index 100% rename from crates/adapters/sqlite-social/src/watchlist.rs rename to crates/adapters/sqlite/src/social/watchlist.rs diff --git a/crates/adapters/sqlite/src/stats.rs b/crates/adapters/sqlite/src/stats.rs index 937ebd03..75d39b4f 100644 --- a/crates/adapters/sqlite/src/stats.rs +++ b/crates/adapters/sqlite/src/stats.rs @@ -32,7 +32,7 @@ impl SqliteStatsRepository { .bind(user_id) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error) + .map_err(crate::shared::map_sqlx_error) } async fn fetch_user_favorite_director( @@ -51,7 +51,7 @@ impl SqliteStatsRepository { .bind(user_id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(row) } @@ -70,7 +70,7 @@ impl SqliteStatsRepository { .bind(user_id) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(row) } } @@ -86,7 +86,7 @@ impl StatsRepository for SqliteStatsRepository { self.fetch_user_most_active_month(&uid) )?; - let most_active_month = most_active.map(|ym| adapter_common::format_year_month(&ym)); + let most_active_month = most_active.map(|ym| crate::shared::format_year_month(&ym)); Ok(UserStats { total_movies: totals.total, @@ -168,14 +168,14 @@ impl StatsRepository for SqliteStatsRepository { .bind(&uid) .fetch_all(&self.pool) ) - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let max_director_count = director_rows.iter().map(|d| d.count).max().unwrap_or(1); let monthly_ratings = rating_rows .into_iter() .map(|r| MonthlyRating { - month_label: adapter_common::format_year_month(&r.month), + month_label: crate::shared::format_year_month(&r.month), year_month: r.month, avg_rating: r.avg_rating, count: r.count, diff --git a/crates/adapters/sqlite/src/user_settings.rs b/crates/adapters/sqlite/src/user_settings.rs index 63868141..73af4174 100644 --- a/crates/adapters/sqlite/src/user_settings.rs +++ b/crates/adapters/sqlite/src/user_settings.rs @@ -28,7 +28,7 @@ impl UserSettingsRepository for SqliteUserSettingsRepository { .bind(&uid) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; match row { Some(r) => { @@ -63,7 +63,7 @@ impl UserSettingsRepository for SqliteUserSettingsRepository { }) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } } @@ -79,7 +79,7 @@ impl UserFederationSettingsQuery for SqliteUserSettingsRepository { .bind(&uid) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; match row { Some(r) => { diff --git a/crates/adapters/sqlite/src/users.rs b/crates/adapters/sqlite/src/users.rs index 9c6abd6a..96793d0d 100644 --- a/crates/adapters/sqlite/src/users.rs +++ b/crates/adapters/sqlite/src/users.rs @@ -68,7 +68,7 @@ impl UserRepository for SqliteUserRepository { .bind(email_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref() .map(|r| Self::row_to_user(r, vec![])) @@ -81,7 +81,7 @@ impl UserRepository for SqliteUserRepository { .bind(username_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref() .map(|r| Self::row_to_user(r, vec![])) @@ -121,7 +121,7 @@ impl UserRepository for SqliteUserRepository { .bind(role) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -132,7 +132,7 @@ impl UserRepository for SqliteUserRepository { .bind(&id_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let Some(r) = row else { return Ok(None) }; @@ -189,7 +189,7 @@ impl UserRepository for SqliteUserRepository { ) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .into_iter() .map(UserSummaryRow::into_domain) .collect() diff --git a/crates/adapters/sqlite/src/watch_event.rs b/crates/adapters/sqlite/src/watch_event.rs index 8864aa91..ff821c82 100644 --- a/crates/adapters/sqlite/src/watch_event.rs +++ b/crates/adapters/sqlite/src/watch_event.rs @@ -7,7 +7,7 @@ use domain::{ }; use sqlx::{Row, SqlitePool}; -use adapter_common::datetime_to_str; +use crate::shared::datetime_to_str; fn parse_uuid(s: &str) -> Result { s.parse() @@ -60,7 +60,7 @@ impl WatchEventCommand for SqliteWatchEventRepository { .bind(&created_at) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -78,7 +78,7 @@ impl WatchEventCommand for SqliteWatchEventRepository { .bind(&id_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -103,7 +103,7 @@ impl WatchEventCommand for SqliteWatchEventRepository { let result = q .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected()) } @@ -117,7 +117,7 @@ impl WatchEventCommand for SqliteWatchEventRepository { .bind(&before_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected()) } } @@ -137,7 +137,7 @@ impl WatchEventQuery for SqliteWatchEventRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_watch_event).collect() } @@ -153,7 +153,7 @@ impl WatchEventQuery for SqliteWatchEventRepository { .bind(&id_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref().map(row_to_watch_event).transpose() } @@ -176,7 +176,7 @@ impl WatchEventQuery for SqliteWatchEventRepository { let rows = q .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_watch_event).collect() } @@ -198,7 +198,7 @@ impl WatchEventQuery for SqliteWatchEventRepository { .bind(&after_str) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .try_get(0) .unwrap_or(0); @@ -207,34 +207,32 @@ impl WatchEventQuery for SqliteWatchEventRepository { } fn row_to_watch_event(row: &sqlx::sqlite::SqliteRow) -> Result { - let id_str: &str = row.try_get("id").map_err(adapter_common::map_sqlx_error)?; + let id_str: &str = row.try_get("id").map_err(crate::shared::map_sqlx_error)?; let user_id_str: &str = row .try_get("user_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let movie_id_str: Option<&str> = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let title: String = row .try_get("title") - .map_err(adapter_common::map_sqlx_error)?; - let year: Option = row - .try_get("year") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; + let year: Option = row.try_get("year").map_err(crate::shared::map_sqlx_error)?; let ext_id: Option = row .try_get("external_metadata_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let source_str: String = row .try_get("source") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let watched_at_str: String = row .try_get("watched_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let status_str: String = row .try_get("status") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let created_at_str: String = row .try_get("created_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let source: WatchEventSource = source_str .parse() @@ -297,7 +295,7 @@ impl WebhookTokenRepository for SqliteWebhookTokenRepository { .bind(&last_used) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -310,7 +308,7 @@ impl WebhookTokenRepository for SqliteWebhookTokenRepository { .bind(hash) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref().map(row_to_webhook_token).transpose() } @@ -325,7 +323,7 @@ impl WebhookTokenRepository for SqliteWebhookTokenRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_webhook_token).collect() } @@ -339,7 +337,7 @@ impl WebhookTokenRepository for SqliteWebhookTokenRepository { .bind(&uid) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if result.rows_affected() == 0 { return Err(DomainError::NotFound(format!("Webhook token {id_str}"))); @@ -356,32 +354,32 @@ impl WebhookTokenRepository for SqliteWebhookTokenRepository { .bind(&id_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } } fn row_to_webhook_token(row: &sqlx::sqlite::SqliteRow) -> Result { - let id_str: &str = row.try_get("id").map_err(adapter_common::map_sqlx_error)?; + let id_str: &str = row.try_get("id").map_err(crate::shared::map_sqlx_error)?; let user_id_str: &str = row .try_get("user_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let token_hash: String = row .try_get("token_hash") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let provider_str: String = row .try_get("provider") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let label: Option = row .try_get("label") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let created_at_str: String = row .try_get("created_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let last_used_str: Option = row .try_get("last_used_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let provider: WatchEventSource = provider_str .parse() diff --git a/crates/adapters/sqlite/src/watchlist.rs b/crates/adapters/sqlite/src/watchlist.rs index 934717c7..ae78e83c 100644 --- a/crates/adapters/sqlite/src/watchlist.rs +++ b/crates/adapters/sqlite/src/watchlist.rs @@ -11,7 +11,7 @@ use domain::{ use sqlx::{Row, SqlitePool}; use crate::models::WatchlistRow; -use adapter_common::datetime_to_str; +use crate::shared::datetime_to_str; pub struct SqliteWatchlistRepository { pool: SqlitePool, @@ -41,7 +41,7 @@ impl WatchlistRepository for SqliteWatchlistRepository { .bind(&added_at) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -56,7 +56,7 @@ impl WatchlistRepository for SqliteWatchlistRepository { .bind(&mid) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if result.rows_affected() == 0 { return Err(DomainError::NotFound(format!( @@ -80,7 +80,7 @@ impl WatchlistRepository for SqliteWatchlistRepository { .bind(&mid) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected() > 0) } @@ -108,13 +108,13 @@ impl WatchlistRepository for SqliteWatchlistRepository { .bind(offset) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let total: i64 = sqlx::query("SELECT COUNT(*) FROM watchlist_entries WHERE user_id = ?") .bind(&uid) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .try_get(0) .unwrap_or(0); @@ -141,7 +141,7 @@ impl WatchlistRepository for SqliteWatchlistRepository { .bind(&mid) .fetch_one(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)? + .map_err(crate::shared::map_sqlx_error)? .try_get(0) .unwrap_or(0); Ok(count > 0) diff --git a/crates/adapters/sqlite/src/wrapup.rs b/crates/adapters/sqlite/src/wrapup.rs index 521c3d1f..1348a0c2 100644 --- a/crates/adapters/sqlite/src/wrapup.rs +++ b/crates/adapters/sqlite/src/wrapup.rs @@ -13,7 +13,7 @@ use domain::{ use sqlx::{Row, SqlitePool}; use uuid::Uuid; -use adapter_common::{parse_datetime, parse_uuid}; +use crate::shared::{parse_datetime, parse_uuid}; fn status_to_str(s: &WrapUpStatus) -> &'static str { match s { @@ -82,7 +82,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&completed) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -102,7 +102,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&id_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -121,7 +121,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&id_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -137,7 +137,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&id_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref().map(row_to_record).transpose() } @@ -153,7 +153,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&uid) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_record).collect() } @@ -166,7 +166,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { ) .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; rows.iter().map(row_to_record).collect() } @@ -195,7 +195,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&end_str) .fetch_optional(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; row.as_ref().map(row_to_record).transpose() } @@ -205,7 +205,7 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(id.value().to_string()) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(()) } @@ -219,37 +219,37 @@ impl WrapUpRepository for SqliteWrapUpRepository { .bind(&before_str) .execute(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; Ok(result.rows_affected()) } } fn row_to_record(row: &sqlx::sqlite::SqliteRow) -> Result { - let id_str: String = row.try_get("id").map_err(adapter_common::map_sqlx_error)?; + let id_str: String = row.try_get("id").map_err(crate::shared::map_sqlx_error)?; let user_id_str: Option = row .try_get("user_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let start_date_str: String = row .try_get("start_date") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let end_date_str: String = row .try_get("end_date") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let status_str: String = row .try_get("status") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let report_json: Option = row .try_get("report_json") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let error_message: Option = row .try_get("error_message") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let created_at_str: String = row .try_get("created_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let completed_at_str: Option = row .try_get("completed_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let user_id = user_id_str.as_deref().map(parse_uuid).transpose()?; @@ -318,7 +318,7 @@ impl WrapUpStatsQuery for SqliteWrapUpStatsQuery { let rows = q .fetch_all(&self.pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if rows.is_empty() { return Ok(vec![]); @@ -330,7 +330,7 @@ impl WrapUpStatsQuery for SqliteWrapUpStatsQuery { for row in &rows { let mid: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; if seen.insert(mid.clone()) { movie_ids.push(mid); } @@ -348,40 +348,40 @@ impl WrapUpStatsQuery for SqliteWrapUpStatsQuery { for row in &rows { let movie_id_str: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let title: String = row .try_get("title") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let release_year: i64 = row .try_get("release_year") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let director: Option = row .try_get("director") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let poster_path: Option = row .try_get("poster_path") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let rating: i64 = row .try_get("rating") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let watched_at_str: String = row .try_get("watched_at") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let user_id_str: String = row .try_get("user_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let runtime_minutes: Option = row .try_get("runtime_minutes") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let budget_usd: Option = row .try_get("budget_usd") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let original_language: Option = row .try_get("original_language") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let watch_medium: Option = row .try_get("watch_medium") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let genres = genres_map.get(&movie_id_str).cloned().unwrap_or_default(); let keywords = keywords_map.get(&movie_id_str).cloned().unwrap_or_default(); @@ -456,16 +456,14 @@ pub(crate) async fn fetch_genres_sqlite( let rows = q .fetch_all(pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let mut map: HashMap> = HashMap::new(); for row in rows { let mid: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; - let name: String = row - .try_get("name") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; + let name: String = row.try_get("name").map_err(crate::shared::map_sqlx_error)?; map.entry(mid).or_default().push(name); } Ok(map) @@ -489,16 +487,14 @@ async fn fetch_keywords_sqlite( let rows = q .fetch_all(pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let mut map: HashMap> = HashMap::new(); for row in rows { let mid: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; - let name: String = row - .try_get("name") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; + let name: String = row.try_get("name").map_err(crate::shared::map_sqlx_error)?; map.entry(mid).or_default().push(name); } Ok(map) @@ -525,25 +521,23 @@ async fn fetch_cast_sqlite( let rows = q .fetch_all(pool) .await - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let mut map: HashMap> = HashMap::new(); for row in rows { let mid: String = row .try_get("movie_id") - .map_err(adapter_common::map_sqlx_error)?; - let name: String = row - .try_get("name") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; + let name: String = row.try_get("name").map_err(crate::shared::map_sqlx_error)?; let billing_order: i32 = row .try_get("billing_order") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let tmdb_person_id: i64 = row .try_get("tmdb_person_id") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; let profile_path: Option = row .try_get("profile_path") - .map_err(adapter_common::map_sqlx_error)?; + .map_err(crate::shared::map_sqlx_error)?; map.entry(mid).or_default().push(CastEntry { name, billing_order: billing_order as u32, diff --git a/crates/adapters/sqlite/tests/migration_ledger_test.rs b/crates/adapters/sqlite/tests/migration_ledger_test.rs index 6c5fbe4b..b226c58a 100644 --- a/crates/adapters/sqlite/tests/migration_ledger_test.rs +++ b/crates/adapters/sqlite/tests/migration_ledger_test.rs @@ -10,9 +10,6 @@ const PRE_MERGE_DB: &str = "tests/fixtures/pre_merge.db"; async fn migrate_with_todays_entry_points(pool: &SqlitePool) { sqlite::migrate(pool).await.unwrap(); - sqlite_event_queue::SqliteEventQueue::create_publisher(pool.clone()) - .await - .unwrap(); } async fn ledger(pool: &SqlitePool) -> String { diff --git a/crates/composition/Cargo.toml b/crates/composition/Cargo.toml index 0599e0de..c0c4bdcd 100644 --- a/crates/composition/Cargo.toml +++ b/crates/composition/Cargo.toml @@ -22,9 +22,6 @@ anyhow = { workspace = true } tracing = { workspace = true } sqlite = { workspace = true } -sqlite-event-queue = { workspace = true } -sqlite-search = { workspace = true } -sqlite-social = { workspace = true } nats = { workspace = true, optional = true } activitypub = { workspace = true, optional = true } sqlite-federation = { workspace = true, optional = true } diff --git a/crates/composition/src/factory.rs b/crates/composition/src/factory.rs index 34580381..f1009836 100644 --- a/crates/composition/src/factory.rs +++ b/crates/composition/src/factory.rs @@ -56,12 +56,12 @@ pub async fn build_database_adapters( .context("SQLite connection failed")?; let (image_ref_command, image_ref_query) = sqlite::create_image_ref(w.pool.clone()); let (pc, pq) = sqlite::create_person_adapter(w.pool.clone()); - let (sc, sp) = sqlite_search::create_search_adapter(w.pool.clone()); + let (sc, sp) = sqlite::create_search_adapter(w.pool.clone()); let pf = sqlite::create_profile_fields_repo(w.pool.clone()); let we = Arc::new(sqlite::SqliteWatchEventRepository::new(w.pool.clone())); let wt: Arc = Arc::new(sqlite::SqliteWebhookTokenRepository::new(w.pool.clone())); - let social = Arc::new(sqlite_social::SqliteSocialRepository::new( + let social = Arc::new(sqlite::SqliteSocialRepository::new( w.pool.clone(), instance.clone(), )); diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index ca4fe627..89010c28 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -44,9 +44,6 @@ infra-wiring = { workspace = true } async-trait = { workspace = true } sqlite = { workspace = true } -sqlite-event-queue = { workspace = true } -sqlite-search = { workspace = true } -sqlite-social = { workspace = true } # Optional — federation activitypub = { workspace = true, optional = true } diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index 72c47a4a..4d7138d0 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs @@ -211,7 +211,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> { federated_profile: Some({ match &db_pool { composition::DbPool::Sqlite(pool) => { - sqlite_social::create_federated_profile_query(pool.clone(), instance.clone()) + sqlite::create_federated_profile_query(pool.clone(), instance.clone()) } } }), @@ -268,7 +268,7 @@ async fn create_event_publisher( tracing::info!("event bus: DB queue"); Ok(match db_pool { composition::DbPool::Sqlite(pool) => { - sqlite_event_queue::SqliteEventQueue::create_publisher(pool.clone()).await? + sqlite::SqliteEventQueue::create_publisher(pool.clone()).await? } }) } diff --git a/crates/worker/Cargo.toml b/crates/worker/Cargo.toml index de04f955..002647b6 100644 --- a/crates/worker/Cargo.toml +++ b/crates/worker/Cargo.toml @@ -40,8 +40,6 @@ infra-wiring = { workspace = true } async-trait = { workspace = true } sqlite = { workspace = true } -sqlite-event-queue = { workspace = true } -sqlite-search = { workspace = true } # Optional — federation activitypub = { workspace = true, optional = true } diff --git a/crates/worker/src/event_bus.rs b/crates/worker/src/event_bus.rs index 556e302d..35814ee6 100644 --- a/crates/worker/src/event_bus.rs +++ b/crates/worker/src/event_bus.rs @@ -14,7 +14,7 @@ pub async fn create( tracing::info!("event bus: DB queue"); match db_pool { DbPool::Sqlite(pool) => { - Ok(sqlite_event_queue::SqliteEventQueue::create_channel(pool.clone()).await?) + Ok(sqlite::SqliteEventQueue::create_channel(pool.clone()).await?) } } }