diff options
Diffstat (limited to 'internal/store')
| -rw-r--r-- | internal/store/sqlite.go | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go index 3879395..f9c9a6b 100644 --- a/internal/store/sqlite.go +++ b/internal/store/sqlite.go @@ -23,6 +23,7 @@ const ( CacheKeyTrelloBoards = "trello_boards" CacheKeyPlanToEatMeals = "plantoeat_meals" CacheKeyGoogleCalendar = "google_calendar" + CacheKeyGoogleTasks = "google_tasks" ) type Store struct { @@ -867,6 +868,110 @@ func (s *Store) GetCalendarEventsByDateRange(start, end time.Time) ([]models.Cal return events, rows.Err() } +// Google Tasks operations + +// SaveGoogleTasks replaces all cached Google Tasks +func (s *Store) SaveGoogleTasks(tasks []models.GoogleTask) error { + tx, err := s.db.Begin() + if err != nil { + return err + } + defer func() { _ = tx.Rollback() }() + + if _, err := tx.Exec(`DELETE FROM google_tasks`); err != nil { + return err + } + + stmt, err := tx.Prepare(` + INSERT INTO google_tasks (id, title, notes, status, completed, due_date, updated_at, list_id, url) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `) + if err != nil { + return err + } + defer func() { _ = stmt.Close() }() + + for _, t := range tasks { + _, err = stmt.Exec(t.ID, t.Title, t.Notes, t.Status, t.Completed, t.DueDate, t.UpdatedAt, t.ListID, t.URL) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// GetGoogleTasks retrieves all cached Google Tasks +func (s *Store) GetGoogleTasks() ([]models.GoogleTask, error) { + rows, err := s.db.Query(` + SELECT id, title, notes, status, completed, due_date, updated_at, list_id, url + FROM google_tasks + ORDER BY completed ASC, CASE WHEN due_date IS NULL THEN 1 ELSE 0 END, due_date ASC + `) + if err != nil { + return nil, err + } + defer func() { _ = rows.Close() }() + + var tasks []models.GoogleTask + for rows.Next() { + var t models.GoogleTask + var dueDate, updatedAt sql.NullTime + + err := rows.Scan(&t.ID, &t.Title, &t.Notes, &t.Status, &t.Completed, &dueDate, &updatedAt, &t.ListID, &t.URL) + if err != nil { + return nil, err + } + + if dueDate.Valid { + t.DueDate = &dueDate.Time + } + if updatedAt.Valid { + t.UpdatedAt = updatedAt.Time + } + + tasks = append(tasks, t) + } + + return tasks, rows.Err() +} + +// GetGoogleTasksByDateRange retrieves cached Google Tasks in a date range +func (s *Store) GetGoogleTasksByDateRange(start, end time.Time) ([]models.GoogleTask, error) { + rows, err := s.db.Query(` + SELECT id, title, notes, status, completed, due_date, updated_at, list_id, url + FROM google_tasks + WHERE due_date IS NULL OR (due_date >= ? AND due_date < ?) + ORDER BY completed ASC, CASE WHEN due_date IS NULL THEN 1 ELSE 0 END, due_date ASC + `, start, end) + if err != nil { + return nil, err + } + defer func() { _ = rows.Close() }() + + var tasks []models.GoogleTask + for rows.Next() { + var t models.GoogleTask + var dueDate, updatedAt sql.NullTime + + err := rows.Scan(&t.ID, &t.Title, &t.Notes, &t.Status, &t.Completed, &dueDate, &updatedAt, &t.ListID, &t.URL) + if err != nil { + return nil, err + } + + if dueDate.Valid { + t.DueDate = &dueDate.Time + } + if updatedAt.Valid { + t.UpdatedAt = updatedAt.Time + } + + tasks = append(tasks, t) + } + + return tasks, rows.Err() +} + // Agent operations // CreateAgentSession creates a new pending agent session @@ -1403,8 +1508,8 @@ func (s *Store) SyncSourceConfigs(source, itemType string, items []models.Source // InvalidateAllCaches removes cache metadata for all known cache keys func (s *Store) InvalidateAllCaches() error { - _, err := s.db.Exec(`DELETE FROM cache_metadata WHERE key IN (?, ?, ?, ?)`, - CacheKeyTodoistTasks, CacheKeyTrelloBoards, CacheKeyPlanToEatMeals, CacheKeyGoogleCalendar) + _, err := s.db.Exec(`DELETE FROM cache_metadata WHERE key IN (?, ?, ?, ?, ?)`, + CacheKeyTodoistTasks, CacheKeyTrelloBoards, CacheKeyPlanToEatMeals, CacheKeyGoogleCalendar, CacheKeyGoogleTasks) return err } |
