Add Google Takeout data import infrastructure

Implements Phase 1 & 2 of Google Takeout RAG integration:
- Database migrations for calendar_events, location_history, search_history
- DAO implementations with hybrid time + semantic search
- Parsers for .ics, JSON, and HTML Google Takeout formats
- Import utilities with batch insert optimization

Features:
- CalendarEventDao: Hybrid time-range + semantic search for events
- LocationHistoryDao: GPS proximity with Haversine distance calculation
- SearchHistoryDao: Semantic-first search (queries are embedding-rich)
- Batch inserts for performance (1M+ records in minutes vs hours)
- OpenTelemetry tracing for all database operations

Import utilities:
- import_calendar: Parse .ics with optional embedding generation
- import_location_history: High-volume GPS data with batch inserts
- import_search_history: Always generates embeddings for semantic search

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Cameron
2026-01-05 14:50:49 -05:00
parent bb23e6bb25
commit d86b2c3746
27 changed files with 3129 additions and 55 deletions

View File

@@ -1,4 +1,37 @@
table! {
// @generated automatically by Diesel CLI.
diesel::table! {
calendar_events (id) {
id -> Integer,
event_uid -> Nullable<Text>,
summary -> Text,
description -> Nullable<Text>,
location -> Nullable<Text>,
start_time -> BigInt,
end_time -> BigInt,
all_day -> Bool,
organizer -> Nullable<Text>,
attendees -> Nullable<Text>,
embedding -> Nullable<Binary>,
created_at -> BigInt,
source_file -> Nullable<Text>,
}
}
diesel::table! {
daily_conversation_summaries (id) {
id -> Integer,
date -> Text,
contact -> Text,
summary -> Text,
message_count -> Integer,
embedding -> Binary,
created_at -> BigInt,
model_version -> Text,
}
}
diesel::table! {
favorites (id) {
id -> Integer,
userid -> Integer,
@@ -6,7 +39,7 @@ table! {
}
}
table! {
diesel::table! {
image_exif (id) {
id -> Integer,
file_path -> Text,
@@ -16,11 +49,11 @@ table! {
width -> Nullable<Integer>,
height -> Nullable<Integer>,
orientation -> Nullable<Integer>,
gps_latitude -> Nullable<Double>,
gps_longitude -> Nullable<Double>,
gps_altitude -> Nullable<Double>,
focal_length -> Nullable<Double>,
aperture -> Nullable<Double>,
gps_latitude -> Nullable<Float>,
gps_longitude -> Nullable<Float>,
gps_altitude -> Nullable<Float>,
focal_length -> Nullable<Float>,
aperture -> Nullable<Float>,
shutter_speed -> Nullable<Text>,
iso -> Nullable<Integer>,
date_taken -> Nullable<BigInt>,
@@ -29,24 +62,49 @@ table! {
}
}
table! {
tagged_photo (id) {
diesel::table! {
knowledge_embeddings (id) {
id -> Integer,
photo_name -> Text,
tag_id -> Integer,
created_time -> BigInt,
keyword -> Text,
description -> Text,
category -> Nullable<Text>,
embedding -> Binary,
created_at -> BigInt,
model_version -> Text,
}
}
table! {
tags (id) {
diesel::table! {
location_history (id) {
id -> Integer,
name -> Text,
created_time -> BigInt,
timestamp -> BigInt,
latitude -> Float,
longitude -> Float,
accuracy -> Nullable<Integer>,
activity -> Nullable<Text>,
activity_confidence -> Nullable<Integer>,
place_name -> Nullable<Text>,
place_category -> Nullable<Text>,
embedding -> Nullable<Binary>,
created_at -> BigInt,
source_file -> Nullable<Text>,
}
}
table! {
diesel::table! {
message_embeddings (id) {
id -> Integer,
contact -> Text,
body -> Text,
timestamp -> BigInt,
is_sent -> Bool,
embedding -> Binary,
created_at -> BigInt,
model_version -> Text,
}
}
diesel::table! {
photo_insights (id) {
id -> Integer,
file_path -> Text,
@@ -57,7 +115,36 @@ table! {
}
}
table! {
diesel::table! {
search_history (id) {
id -> Integer,
timestamp -> BigInt,
query -> Text,
search_engine -> Nullable<Text>,
embedding -> Binary,
created_at -> BigInt,
source_file -> Nullable<Text>,
}
}
diesel::table! {
tagged_photo (id) {
id -> Integer,
photo_name -> Text,
tag_id -> Integer,
created_time -> BigInt,
}
}
diesel::table! {
tags (id) {
id -> Integer,
name -> Text,
created_time -> BigInt,
}
}
diesel::table! {
users (id) {
id -> Integer,
username -> Text,
@@ -65,12 +152,18 @@ table! {
}
}
joinable!(tagged_photo -> tags (tag_id));
diesel::joinable!(tagged_photo -> tags (tag_id));
allow_tables_to_appear_in_same_query!(
diesel::allow_tables_to_appear_in_same_query!(
calendar_events,
daily_conversation_summaries,
favorites,
image_exif,
knowledge_embeddings,
location_history,
message_embeddings,
photo_insights,
search_history,
tagged_photo,
tags,
users,