summaryrefslogtreecommitdiff
path: root/internal/store/sqlite.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-20 10:40:29 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-20 10:40:29 -1000
commit6a59098c3096f5ebd3a61ef5268cbd480b0f1519 (patch)
tree2192861ed6db801c030be9b67f05796c85bad20c /internal/store/sqlite.go
parent59227d33d6e7c01fbb1ebf96ea616c5f296df7b1 (diff)
Implement efficient sync for Todoist and Trello APIs
- Add Todoist Sync API v9 support with incremental sync tokens - Store sync tokens in SQLite for persistence across restarts - Add field filtering to Trello API calls to reduce payload size - Update handlers to use incremental sync (merge changes vs full replace) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/store/sqlite.go')
-rw-r--r--internal/store/sqlite.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go
index a078748..b8d0c97 100644
--- a/internal/store/sqlite.go
+++ b/internal/store/sqlite.go
@@ -186,6 +186,54 @@ func (s *Store) DeleteTask(id string) error {
return err
}
+// UpsertTask inserts or updates a single task
+func (s *Store) UpsertTask(task models.Task) error {
+ labelsJSON, _ := json.Marshal(task.Labels)
+ _, err := s.db.Exec(`
+ INSERT OR REPLACE INTO tasks
+ (id, content, description, project_id, project_name, due_date, priority, completed, labels, url, created_at, updated_at)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
+ `,
+ task.ID,
+ task.Content,
+ task.Description,
+ task.ProjectID,
+ task.ProjectName,
+ task.DueDate,
+ task.Priority,
+ task.Completed,
+ string(labelsJSON),
+ task.URL,
+ task.CreatedAt,
+ )
+ return err
+}
+
+// DeleteTasksByIDs removes multiple tasks by ID
+func (s *Store) DeleteTasksByIDs(ids []string) error {
+ if len(ids) == 0 {
+ return nil
+ }
+ tx, err := s.db.Begin()
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
+
+ stmt, err := tx.Prepare(`DELETE FROM tasks WHERE id = ?`)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+
+ for _, id := range ids {
+ if _, err := stmt.Exec(id); err != nil {
+ return err
+ }
+ }
+ return tx.Commit()
+}
+
// Notes operations
// SaveNotes saves multiple notes to the database
@@ -578,3 +626,33 @@ func (s *Store) DeleteCard(id string) error {
_, err := s.db.Exec(`DELETE FROM cards WHERE id = ?`, id)
return err
}
+
+// Sync token operations
+
+// GetSyncToken retrieves the sync token for a service
+func (s *Store) GetSyncToken(service string) (string, error) {
+ var token string
+ err := s.db.QueryRow(`SELECT token FROM sync_tokens WHERE service = ?`, service).Scan(&token)
+ if err == sql.ErrNoRows {
+ return "", nil
+ }
+ if err != nil {
+ return "", err
+ }
+ return token, nil
+}
+
+// SetSyncToken saves the sync token for a service
+func (s *Store) SetSyncToken(service, token string) error {
+ _, err := s.db.Exec(`
+ INSERT OR REPLACE INTO sync_tokens (service, token, updated_at)
+ VALUES (?, ?, CURRENT_TIMESTAMP)
+ `, service, token)
+ return err
+}
+
+// ClearSyncToken removes the sync token for a service
+func (s *Store) ClearSyncToken(service string) error {
+ _, err := s.db.Exec(`DELETE FROM sync_tokens WHERE service = ?`, service)
+ return err
+}