summaryrefslogtreecommitdiff
path: root/internal/store/sqlite.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/store/sqlite.go')
-rw-r--r--internal/store/sqlite.go85
1 files changed, 47 insertions, 38 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go
index a6e9fd4..f955f71 100644
--- a/internal/store/sqlite.go
+++ b/internal/store/sqlite.go
@@ -292,8 +292,8 @@ func (s *Store) SaveBoards(boards []models.Board) error {
// Save cards
cardStmt, err := tx.Prepare(`
INSERT OR REPLACE INTO cards
- (id, name, board_id, list_id, list_name, due_date, url, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
+ (id, name, description, board_id, list_id, list_name, due_date, url, updated_at)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
`)
if err != nil {
return err
@@ -315,6 +315,7 @@ func (s *Store) SaveBoards(boards []models.Board) error {
_, err := cardStmt.Exec(
card.ID,
card.Name,
+ card.Description,
board.ID,
card.ListID,
card.ListName,
@@ -372,7 +373,7 @@ func (s *Store) GetBoards() ([]models.Board, error) {
// Fetch cards
cardRows, err := s.db.Query(`
- SELECT id, name, board_id, list_id, list_name, due_date, url
+ SELECT id, name, description, board_id, list_id, list_name, due_date, url
FROM cards
ORDER BY board_id, list_name, name
`)
@@ -389,6 +390,7 @@ func (s *Store) GetBoards() ([]models.Board, error) {
err := cardRows.Scan(
&card.ID,
&card.Name,
+ &card.Description,
&boardID,
&card.ListID,
&card.ListName,
@@ -696,22 +698,29 @@ func (s *Store) SaveGoogleTasks(tasks []models.GoogleTask) error {
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
+// parseGoogleTaskTime parses a TEXT-column timestamp written by mattn/go-sqlite3's
+// default time.Time binding. The google_tasks.due_date/updated_at columns are declared
+// TEXT (not DATETIME), so the driver never auto-converts them back to time.Time on read.
+func parseGoogleTaskTime(s string) (time.Time, bool) {
+ for _, layout := range []string{
+ "2006-01-02 15:04:05.999999999-07:00",
+ time.RFC3339Nano,
+ time.RFC3339,
+ "2006-01-02 15:04:05",
+ "2006-01-02",
+ } {
+ if parsed, err := time.Parse(layout, s); err == nil {
+ return parsed, true
+ }
}
- defer func() { _ = rows.Close() }()
+ return time.Time{}, false
+}
+func scanGoogleTasks(rows *sql.Rows) ([]models.GoogleTask, error) {
var tasks []models.GoogleTask
for rows.Next() {
var t models.GoogleTask
- var dueDate, updatedAt sql.NullTime
+ var dueDate, updatedAt sql.NullString
err := rows.Scan(&t.ID, &t.Title, &t.Notes, &t.Status, &t.Completed, &dueDate, &updatedAt, &t.ListID, &t.URL)
if err != nil {
@@ -719,10 +728,14 @@ func (s *Store) GetGoogleTasks() ([]models.GoogleTask, error) {
}
if dueDate.Valid {
- t.DueDate = &dueDate.Time
+ if parsed, ok := parseGoogleTaskTime(dueDate.String); ok {
+ t.DueDate = &parsed
+ }
}
if updatedAt.Valid {
- t.UpdatedAt = updatedAt.Time
+ if parsed, ok := parseGoogleTaskTime(updatedAt.String); ok {
+ t.UpdatedAt = parsed
+ }
}
tasks = append(tasks, t)
@@ -731,40 +744,36 @@ func (s *Store) GetGoogleTasks() ([]models.GoogleTask, error) {
return tasks, rows.Err()
}
-// GetGoogleTasksByDateRange retrieves cached Google Tasks in a date range
-func (s *Store) GetGoogleTasksByDateRange(start, end time.Time) ([]models.GoogleTask, error) {
+// 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
- 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
- }
+ return scanGoogleTasks(rows)
+}
- tasks = append(tasks, t)
+// GetGoogleTasksByDateRange retrieves cached Google Tasks due before end, including overdue
+// tasks (due before start) so they keep appearing until completed.
+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 < ?
+ ORDER BY completed ASC, CASE WHEN due_date IS NULL THEN 1 ELSE 0 END, due_date ASC
+ `, end)
+ if err != nil {
+ return nil, err
}
+ defer func() { _ = rows.Close() }()
- return tasks, rows.Err()
+ return scanGoogleTasks(rows)
}
// Agent operations