fix: batch N+1 queries in import duplicate check and watch event dismiss
Some checks failed
CI / Check / Test (push) Failing after 5m54s
Some checks failed
CI / Check / Test (push) Failing after 5m54s
apply_mapping: 2 batch queries instead of up to 2N per-row lookups dismiss: single fetch + single update instead of 2N per-event queries
This commit is contained in:
@@ -100,6 +100,14 @@ pub trait MovieRepository: Send + Sync {
|
||||
) -> Result<Vec<Movie>, DomainError>;
|
||||
async fn upsert_movie(&self, movie: &Movie) -> Result<(), DomainError>;
|
||||
async fn delete_movie(&self, movie_id: &MovieId) -> Result<(), DomainError>;
|
||||
async fn existing_external_ids(
|
||||
&self,
|
||||
ids: &[ExternalMetadataId],
|
||||
) -> Result<std::collections::HashSet<String>, DomainError>;
|
||||
async fn existing_title_year_pairs(
|
||||
&self,
|
||||
pairs: &[(MovieTitle, ReleaseYear)],
|
||||
) -> Result<std::collections::HashSet<(String, u16)>, DomainError>;
|
||||
async fn list_movies(
|
||||
&self,
|
||||
page: &collections::PageParams,
|
||||
@@ -434,6 +442,12 @@ pub trait WatchEventRepository: Send + Sync {
|
||||
) -> Result<(), DomainError>;
|
||||
async fn list_pending(&self, user_id: &UserId) -> Result<Vec<WatchEvent>, DomainError>;
|
||||
async fn get_by_id(&self, id: &WatchEventId) -> Result<Option<WatchEvent>, DomainError>;
|
||||
async fn get_by_ids(&self, ids: &[WatchEventId]) -> Result<Vec<WatchEvent>, DomainError>;
|
||||
async fn update_status_batch(
|
||||
&self,
|
||||
ids: &[WatchEventId],
|
||||
status: WatchEventStatus,
|
||||
) -> Result<u64, DomainError>;
|
||||
async fn find_duplicate(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
|
||||
@@ -97,6 +97,38 @@ impl MovieRepository for InMemoryMovieRepository {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn existing_external_ids(
|
||||
&self,
|
||||
ids: &[ExternalMetadataId],
|
||||
) -> Result<std::collections::HashSet<String>, DomainError> {
|
||||
let store = self.store.lock().unwrap();
|
||||
let known: std::collections::HashSet<String> = store
|
||||
.values()
|
||||
.filter_map(|m| m.external_metadata_id().map(|e| e.value().to_string()))
|
||||
.collect();
|
||||
Ok(ids
|
||||
.iter()
|
||||
.map(|id| id.value().to_string())
|
||||
.filter(|v| known.contains(v))
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn existing_title_year_pairs(
|
||||
&self,
|
||||
pairs: &[(MovieTitle, ReleaseYear)],
|
||||
) -> Result<std::collections::HashSet<(String, u16)>, DomainError> {
|
||||
let store = self.store.lock().unwrap();
|
||||
let known: std::collections::HashSet<(String, u16)> = store
|
||||
.values()
|
||||
.map(|m| (m.title().value().to_string(), m.release_year().value()))
|
||||
.collect();
|
||||
Ok(pairs
|
||||
.iter()
|
||||
.map(|(t, y)| (t.value().to_string(), y.value()))
|
||||
.filter(|p| known.contains(p))
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn list_movies(
|
||||
&self,
|
||||
_page: &crate::models::collections::PageParams,
|
||||
@@ -868,6 +900,19 @@ impl crate::ports::WatchEventRepository for PanicWatchEventRepository {
|
||||
) -> Result<Option<crate::models::WatchEvent>, DomainError> {
|
||||
panic!("PanicWatchEventRepository called")
|
||||
}
|
||||
async fn get_by_ids(
|
||||
&self,
|
||||
_: &[crate::value_objects::WatchEventId],
|
||||
) -> Result<Vec<crate::models::WatchEvent>, DomainError> {
|
||||
panic!("PanicWatchEventRepository called")
|
||||
}
|
||||
async fn update_status_batch(
|
||||
&self,
|
||||
_: &[crate::value_objects::WatchEventId],
|
||||
_: crate::models::WatchEventStatus,
|
||||
) -> Result<u64, DomainError> {
|
||||
panic!("PanicWatchEventRepository called")
|
||||
}
|
||||
async fn find_duplicate(
|
||||
&self,
|
||||
_: &UserId,
|
||||
|
||||
Reference in New Issue
Block a user