refactor: merge sqlite adapter family into one crate

This commit is contained in:
2026-10-25 20:48:30 +01:00
parent 1ece8032ff
commit 67597ec9a6
62 changed files with 292 additions and 442 deletions

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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}"))
}

View File

@@ -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 }

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 _,

View File

@@ -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 {

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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::<Result<Vec<_>, _>>()?;
@@ -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)
}
}

View File

@@ -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<Self> {
migrations::run(&pool).await?;
Ok(Self {
pool,
config: Arc::new(config),

View File

@@ -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()
}

View File

@@ -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<Vec<ImportProfile>, 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)
}
}

View File

@@ -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<u64, DomainError> {
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)
}
}

View File

@@ -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<String, Vec<String>> = 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<String> = 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)?,

View File

@@ -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<dyn domain::ports::UserProfileFieldsRepository> {
@@ -122,9 +137,7 @@ pub async fn wire(database_url: &str) -> anyhow::Result<SqliteWireOutput> {
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 _,
})
}

View File

@@ -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,
};

View File

@@ -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()

View File

@@ -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)
}

View File

@@ -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()

View File

@@ -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<Option<MovieProfile>, 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::<i64, _>("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::<i64, _>("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::<i64, _>("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::<i64, _>("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()

View File

@@ -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(())

View File

@@ -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())
}
}

View File

@@ -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()

View File

@@ -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;

View File

@@ -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},
};

View File

@@ -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<uuid::Uuid, DomainError> {
pub(crate) fn parse_uuid(s: &str) -> Result<uuid::Uuid, DomainError> {
uuid::Uuid::parse_str(s)
.map_err(|e| DomainError::InfrastructureError(format!("Invalid UUID '{}': {}", s, e)))
}
pub fn parse_datetime(s: &str) -> Result<chrono::NaiveDateTime, DomainError> {
pub(crate) fn parse_datetime(s: &str) -> Result<chrono::NaiveDateTime, DomainError> {
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<String>,
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<String>,
runtime_minutes: Option<i64>,
@@ -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<f64>,
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 }
}

View File

@@ -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()
}

View File

@@ -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 {

View File

@@ -1,6 +1,6 @@
mod federated_profile;
mod follow_repository;
mod social;
mod local_social;
mod watchlist;
pub mod ap_content;

View File

@@ -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| {

View File

@@ -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,

View File

@@ -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) => {

View File

@@ -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()

View File

@@ -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<uuid::Uuid, DomainError> {
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<WatchEvent, DomainError> {
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<i64> = row
.try_get("year")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let year: Option<i64> = row.try_get("year").map_err(crate::shared::map_sqlx_error)?;
let ext_id: Option<String> = 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<WebhookToken, DomainError> {
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<String> = 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<String> = 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()

View File

@@ -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)

View File

@@ -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<WrapUpRecord, DomainError> {
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<String> = 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<String> = row
.try_get("report_json")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let error_message: Option<String> = 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<String> = 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<String> = row
.try_get("director")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let poster_path: Option<String> = 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<i32> = row
.try_get("runtime_minutes")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let budget_usd: Option<i64> = row
.try_get("budget_usd")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let original_language: Option<String> = row
.try_get("original_language")
.map_err(adapter_common::map_sqlx_error)?;
.map_err(crate::shared::map_sqlx_error)?;
let watch_medium: Option<String> = 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<String, Vec<String>> = 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<String, Vec<String>> = 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<String, Vec<CastEntry>> = 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<String> = 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,

View File

@@ -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 {

View File

@@ -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 }

View File

@@ -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<dyn WebhookTokenRepository> =
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(),
));

View File

@@ -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 }

View File

@@ -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?
}
})
}

View File

@@ -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 }

View File

@@ -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?)
}
}
}