fix incremental sync

This commit is contained in:
Erik Winter 2025-01-05 14:37:46 +01:00
parent 83affc6cac
commit 1944c67a4a
7 changed files with 33 additions and 14 deletions

BIN
dist/plan vendored

Binary file not shown.

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"time"
"go-mod.ewintr.nl/planner/item"
"go-mod.ewintr.nl/planner/plan/storage"
@ -39,17 +40,21 @@ func (s Sync) Do(deps Dependencies) (CommandResult, error) {
}
// get new/updated items
ts, err := deps.SyncRepo.LastUpdate()
oldTS, err := deps.SyncRepo.LastUpdate()
if err != nil {
return nil, fmt.Errorf("could not find timestamp of last update: %v", err)
}
recItems, err := deps.SyncClient.Updated([]item.Kind{item.KindTask}, ts)
recItems, err := deps.SyncClient.Updated([]item.Kind{item.KindTask}, oldTS)
if err != nil {
return nil, fmt.Errorf("could not receive updates: %v", err)
}
updated := make([]item.Item, 0)
var newTS time.Time
for _, ri := range recItems {
if ri.Updated.After(newTS) {
newTS = ri.Updated
}
if ri.Deleted {
if err := deps.LocalIDRepo.Delete(ri.ID); err != nil && !errors.Is(err, storage.ErrNotFound) {
return nil, fmt.Errorf("could not delete local id: %v", err)
@ -94,6 +99,10 @@ func (s Sync) Do(deps Dependencies) (CommandResult, error) {
}
}
if err := deps.SyncRepo.SetLastUpdate(newTS); err != nil {
return nil, fmt.Errorf("could not store update timestamp: %v", err)
}
return SyncResult{}, nil
}

View File

@ -52,6 +52,10 @@ func (r *Sync) DeleteAll() error {
return nil
}
func (r *Sync) SetLastUpdate(ts time.Time) error {
return nil
}
func (r *Sync) LastUpdate() (time.Time, error) {
r.mutex.RLock()
defer r.mutex.RUnlock()

View File

@ -39,6 +39,9 @@ var migrations = []string{
`INSERT INTO localids (id, local_id)
SELECT id, local_id FROM localids_backup`,
`DROP TABLE localids_backup`,
`ALTER TABLE items ADD COLUMN date TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE tasks ADD COLUMN project TEXT NOT NULL DEFAULT ''`,
`CREATE TABLE syncupdate ("timestamp" TIMESTAMP NOT NULL)`,
`INSERT INTO syncupdate (timestamp) VALUES ("0001-01-01T00:00:00Z")`,
}

View File

@ -84,20 +84,22 @@ func (s *SqliteSync) DeleteAll() error {
return nil
}
func (s *SqliteSync) SetLastUpdate(ts time.Time) error {
if _, err := s.db.Exec(`UPDATE syncupdate SET timestamp = ?`, ts.Format(time.RFC3339)); err != nil {
return fmt.Errorf("%w: could not store timestamp: %v", ErrSqliteFailure, err)
}
return nil
}
func (s *SqliteSync) LastUpdate() (time.Time, error) {
var updatedStr sql.NullString
err := s.db.QueryRow("SELECT MAX(updated) FROM items").Scan(&updatedStr)
if err != nil {
var tsStr string
if err := s.db.QueryRow("SELECT timestamp FROM syncupdate").Scan(&tsStr); err != nil {
return time.Time{}, fmt.Errorf("%w: failed to get last update: %v", ErrSqliteFailure, err)
}
if !updatedStr.Valid {
return time.Time{}, nil // Return zero time if NULL or no rows
}
lastUpdate, err := time.Parse(time.RFC3339, updatedStr.String)
ts, err := time.Parse(time.RFC3339, tsStr)
if err != nil {
return time.Time{}, fmt.Errorf("%w: failed to parse last update time: %v", ErrSqliteFailure, err)
return time.Time{}, fmt.Errorf("%w: could not convert db timstamp into time.Time: %v", ErrSqliteFailure, err)
}
return lastUpdate, nil
return ts, nil
}

View File

@ -25,6 +25,7 @@ type Sync interface {
FindAll() ([]item.Item, error)
Store(i item.Item) error
DeleteAll() error
SetLastUpdate(ts time.Time) error
LastUpdate() (time.Time, error)
}

View File

@ -59,7 +59,7 @@ func (c *HTTP) Updated(ks []item.Kind, ts time.Time) ([]item.Item, error) {
}
u := fmt.Sprintf("%s/sync?ks=%s", c.baseURL, strings.Join(ksStr, ","))
if !ts.IsZero() {
u = fmt.Sprintf("%s&ts=", url.QueryEscape(ts.Format(time.RFC3339)))
u = fmt.Sprintf("%s&ts=%s", u, url.QueryEscape(ts.Format(time.RFC3339)))
}
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {