fix incremental sync
This commit is contained in:
parent
83affc6cac
commit
1944c67a4a
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")`,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue