diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-23 21:37:18 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-23 21:37:18 -1000 |
| commit | 465093343ddd398ce5f6377fc9c472d8251c618b (patch) | |
| tree | d333a2f1c8879f7b114817e929c95e9fcf5f4c3b /internal/store/sqlite.go | |
| parent | e23c85577cbb0eac8b847dd989072698ff4e7a30 (diff) | |
Refactor: reduce code duplication with shared abstractions
- Add BaseClient HTTP abstraction (internal/api/http.go) to eliminate
duplicated HTTP boilerplate across Todoist, Trello, and PlanToEat clients
- Add response helpers (internal/handlers/response.go) for JSON/HTML responses
- Add generic cache wrapper (internal/handlers/cache.go) using Go generics
- Consolidate HandleCompleteAtom/HandleUncompleteAtom into handleAtomToggle
- Merge TabsHandler into Handler, delete tabs.go
- Extract sortTasksByUrgency and filterAndSortTrelloTasks helpers
- Update tests to work with new BaseClient structure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/store/sqlite.go')
| -rw-r--r-- | internal/store/sqlite.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go index a4d01a2..5b67234 100644 --- a/internal/store/sqlite.go +++ b/internal/store/sqlite.go @@ -595,3 +595,100 @@ func (s *Store) GetBugs() ([]Bug, error) { } return bugs, rows.Err() } + +// GetTasksByDateRange retrieves tasks due within a specific date range +func (s *Store) GetTasksByDateRange(start, end time.Time) ([]models.Task, error) { + rows, err := s.db.Query(` + SELECT id, content, description, project_id, project_name, due_date, priority, completed, labels, url, created_at + FROM tasks + WHERE due_date BETWEEN ? AND ? + ORDER BY due_date ASC, priority DESC + `, start, end) + if err != nil { + return nil, err + } + defer rows.Close() + + var tasks []models.Task + for rows.Next() { + var task models.Task + var labelsJSON string + var dueDate sql.NullTime + + err := rows.Scan( + &task.ID, + &task.Content, + &task.Description, + &task.ProjectID, + &task.ProjectName, + &dueDate, + &task.Priority, + &task.Completed, + &labelsJSON, + &task.URL, + &task.CreatedAt, + ) + if err != nil { + return nil, err + } + + if dueDate.Valid { + task.DueDate = &dueDate.Time + } + + if err := json.Unmarshal([]byte(labelsJSON), &task.Labels); err != nil { + log.Printf("Warning: failed to unmarshal labels for task %s: %v", task.ID, err) + task.Labels = []string{} + } + tasks = append(tasks, task) + } + + return tasks, rows.Err() +} + +// GetMealsByDateRange retrieves meals within a specific date range +func (s *Store) GetMealsByDateRange(start, end time.Time) ([]models.Meal, error) { + return s.GetMeals(start, end) +} + +// GetCardsByDateRange retrieves cards due within a specific date range +func (s *Store) GetCardsByDateRange(start, end time.Time) ([]models.Card, error) { + rows, err := s.db.Query(` + SELECT c.id, c.name, b.name, c.list_id, c.list_name, c.due_date, c.url + FROM cards c + JOIN boards b ON c.board_id = b.id + WHERE c.due_date BETWEEN ? AND ? + ORDER BY c.due_date ASC + `, start, end) + if err != nil { + return nil, err + } + defer rows.Close() + + var cards []models.Card + for rows.Next() { + var card models.Card + var dueDate sql.NullTime + + err := rows.Scan( + &card.ID, + &card.Name, + &card.BoardName, + &card.ListID, + &card.ListName, + &dueDate, + &card.URL, + ) + if err != nil { + return nil, err + } + + if dueDate.Valid { + card.DueDate = &dueDate.Time + } + + cards = append(cards, card) + } + + return cards, rows.Err() +} |
