feat: add tag_dao to InsightGenerator for tag-based context enrichment
Threads SqliteTagDao through InsightGenerator and AppState (both default and test_state). Adds Send+Sync bounds to TagDao trait with unsafe impls for SqliteTagDao (always Mutex-protected) and TestTagDao (single-threaded). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ use crate::database::models::InsertPhotoInsight;
|
|||||||
use crate::database::{
|
use crate::database::{
|
||||||
CalendarEventDao, DailySummaryDao, ExifDao, InsightDao, LocationHistoryDao, SearchHistoryDao,
|
CalendarEventDao, DailySummaryDao, ExifDao, InsightDao, LocationHistoryDao, SearchHistoryDao,
|
||||||
};
|
};
|
||||||
|
use crate::tags::TagDao;
|
||||||
use crate::memories::extract_date_from_filename;
|
use crate::memories::extract_date_from_filename;
|
||||||
use crate::otel::global_tracer;
|
use crate::otel::global_tracer;
|
||||||
use crate::utils::normalize_path;
|
use crate::utils::normalize_path;
|
||||||
@@ -45,6 +46,7 @@ pub struct InsightGenerator {
|
|||||||
calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>>,
|
calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>>,
|
||||||
location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>>,
|
location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>>,
|
||||||
search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>>,
|
search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>>,
|
||||||
|
tag_dao: Arc<Mutex<Box<dyn TagDao>>>,
|
||||||
|
|
||||||
base_path: String,
|
base_path: String,
|
||||||
}
|
}
|
||||||
@@ -59,6 +61,7 @@ impl InsightGenerator {
|
|||||||
calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>>,
|
calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>>,
|
||||||
location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>>,
|
location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>>,
|
||||||
search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>>,
|
search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>>,
|
||||||
|
tag_dao: Arc<Mutex<Box<dyn TagDao>>>,
|
||||||
base_path: String,
|
base_path: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -70,6 +73,7 @@ impl InsightGenerator {
|
|||||||
calendar_dao,
|
calendar_dao,
|
||||||
location_dao,
|
location_dao,
|
||||||
search_dao,
|
search_dao,
|
||||||
|
tag_dao,
|
||||||
base_path,
|
base_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::database::{
|
|||||||
SqliteLocationHistoryDao, SqliteSearchHistoryDao,
|
SqliteLocationHistoryDao, SqliteSearchHistoryDao,
|
||||||
};
|
};
|
||||||
use crate::database::{PreviewDao, SqlitePreviewDao};
|
use crate::database::{PreviewDao, SqlitePreviewDao};
|
||||||
|
use crate::tags::{SqliteTagDao, TagDao};
|
||||||
use crate::video::actors::{
|
use crate::video::actors::{
|
||||||
PlaylistGenerator, PreviewClipGenerator, StreamActor, VideoPlaylistManager,
|
PlaylistGenerator, PreviewClipGenerator, StreamActor, VideoPlaylistManager,
|
||||||
};
|
};
|
||||||
@@ -119,6 +120,8 @@ impl Default for AppState {
|
|||||||
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
||||||
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
||||||
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
||||||
|
let tag_dao: Arc<Mutex<Box<dyn TagDao>>> =
|
||||||
|
Arc::new(Mutex::new(Box::new(SqliteTagDao::default())));
|
||||||
|
|
||||||
// Load base path
|
// Load base path
|
||||||
let base_path = env::var("BASE_PATH").expect("BASE_PATH was not set in the env");
|
let base_path = env::var("BASE_PATH").expect("BASE_PATH was not set in the env");
|
||||||
@@ -133,6 +136,7 @@ impl Default for AppState {
|
|||||||
calendar_dao.clone(),
|
calendar_dao.clone(),
|
||||||
location_dao.clone(),
|
location_dao.clone(),
|
||||||
search_dao.clone(),
|
search_dao.clone(),
|
||||||
|
tag_dao.clone(),
|
||||||
base_path.clone(),
|
base_path.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -196,6 +200,8 @@ impl AppState {
|
|||||||
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
||||||
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
||||||
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
||||||
|
let tag_dao: Arc<Mutex<Box<dyn TagDao>>> =
|
||||||
|
Arc::new(Mutex::new(Box::new(SqliteTagDao::default())));
|
||||||
|
|
||||||
// Initialize test InsightGenerator with all data sources
|
// Initialize test InsightGenerator with all data sources
|
||||||
let base_path_str = base_path.to_string_lossy().to_string();
|
let base_path_str = base_path.to_string_lossy().to_string();
|
||||||
@@ -208,6 +214,7 @@ impl AppState {
|
|||||||
calendar_dao.clone(),
|
calendar_dao.clone(),
|
||||||
location_dao.clone(),
|
location_dao.clone(),
|
||||||
search_dao.clone(),
|
search_dao.clone(),
|
||||||
|
tag_dao.clone(),
|
||||||
base_path_str.clone(),
|
base_path_str.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
10
src/tags.rs
10
src/tags.rs
@@ -276,7 +276,7 @@ pub struct AddTagsRequest {
|
|||||||
pub tag_ids: Vec<i32>,
|
pub tag_ids: Vec<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TagDao {
|
pub trait TagDao: Send + Sync {
|
||||||
fn get_all_tags(
|
fn get_all_tags(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &opentelemetry::Context,
|
context: &opentelemetry::Context,
|
||||||
@@ -345,6 +345,10 @@ impl Default for SqliteTagDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: SqliteTagDao is always accessed through Arc<Mutex<...>>,
|
||||||
|
// so concurrent access is prevented by the Mutex.
|
||||||
|
unsafe impl Sync for SqliteTagDao {}
|
||||||
|
|
||||||
impl TagDao for SqliteTagDao {
|
impl TagDao for SqliteTagDao {
|
||||||
fn get_all_tags(
|
fn get_all_tags(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -735,6 +739,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: TestTagDao is only used in single-threaded tests
|
||||||
|
unsafe impl Send for TestTagDao {}
|
||||||
|
unsafe impl Sync for TestTagDao {}
|
||||||
|
|
||||||
impl TagDao for TestTagDao {
|
impl TagDao for TestTagDao {
|
||||||
fn get_all_tags(
|
fn get_all_tags(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
Reference in New Issue
Block a user