keep relevant local updates

This commit is contained in:
Erik Winter 2021-08-24 07:26:58 +02:00
parent ff86bab8ba
commit 41a27a4799
3 changed files with 52 additions and 17 deletions

View File

@ -12,6 +12,9 @@ type localData struct {
} }
// Memory is an in memory implementation of LocalRepository // Memory is an in memory implementation of LocalRepository
//
// It is meant for testing and does not make an attempt to
// keep local state between consecutive calls to SetTasks()
type Memory struct { type Memory struct {
tasks []*task.Task tasks []*task.Task
latestSync time.Time latestSync time.Time

View File

@ -76,7 +76,13 @@ func (s *Sqlite) SetTasks(tasks []*task.Task) error {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
localIdMap := map[string]int{} type localTaskInfo struct {
TaskId string
TaskVersion int
LocalId int
LocalUpdate task.LocalUpdate
}
localIdMap := map[string]localTaskInfo{}
for _, t := range tasks { for _, t := range tasks {
var recurStr string var recurStr string
if t.Recur != nil { if t.Recur != nil {
@ -92,11 +98,17 @@ VALUES
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
localIdMap[t.Id] = 0 localIdMap[t.Id] = localTaskInfo{
TaskId: t.Id,
TaskVersion: t.Version,
LocalId: 0,
LocalUpdate: task.LocalUpdate{},
}
} }
// set local_ids // set local_ids and local_updates:
rows, err := s.db.Query(`SELECT id, local_id FROM local_task`) // 1 - find existing
rows, err := s.db.Query(`SELECT id, local_id, local_update FROM local_task`)
if err != nil { if err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
@ -104,39 +116,55 @@ VALUES
for rows.Next() { for rows.Next() {
var id string var id string
var localId int var localId int
if err := rows.Scan(&id, &localId); err != nil { var localUpdate task.LocalUpdate
if err := rows.Scan(&id, &localId, &localUpdate); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
if _, ok := localIdMap[id]; ok { if oldInfo, ok := localIdMap[id]; ok {
localIdMap[id] = localId newInfo := localTaskInfo{
TaskId: oldInfo.TaskId,
TaskVersion: oldInfo.TaskVersion,
LocalId: localId,
LocalUpdate: localUpdate,
}
localIdMap[id] = newInfo
} }
} }
// 2 - remove old values
if _, err := s.db.Exec(`DELETE FROM local_task`); err != nil { if _, err := s.db.Exec(`DELETE FROM local_task`); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
// 3 - figure out new values
var used []int var used []int
for _, localId := range localIdMap { for _, info := range localIdMap {
if localId != 0 { if info.LocalId != 0 {
used = append(used, localId) used = append(used, info.LocalId)
} }
} }
for id, info := range localIdMap {
for id, localId := range localIdMap { newInfo := info
if localId == 0 { // find new local_id when needed
if info.LocalId == 0 {
newLocalId := NextLocalId(used) newLocalId := NextLocalId(used)
localIdMap[id] = newLocalId
used = append(used, newLocalId) used = append(used, newLocalId)
newInfo.LocalId = newLocalId
} }
// remove local_update when outdated
if info.LocalUpdate.ForVersion < info.TaskVersion {
newInfo.LocalUpdate = task.LocalUpdate{}
}
localIdMap[id] = newInfo
} }
for id, localId := range localIdMap { // 4 - store new values
for id, info := range localIdMap {
if _, err := s.db.Exec(` if _, err := s.db.Exec(`
INSERT INTO local_task INSERT INTO local_task
(id, local_id) (id, local_id, local_update)
VALUES VALUES
(?, ?)`, id, localId); err != nil { (?, ?, ?)`, id, info.LocalId, info.LocalUpdate); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
} }

View File

@ -13,6 +13,10 @@ type LocalTask struct {
LocalUpdate *LocalUpdate LocalUpdate *LocalUpdate
} }
func (lt *LocalTask) HasUpdate() bool {
return lt.LocalUpdate.ForVersion != 0
}
func (lt *LocalTask) AddUpdate(update *LocalUpdate) { func (lt *LocalTask) AddUpdate(update *LocalUpdate) {
if lt.LocalUpdate == nil { if lt.LocalUpdate == nil {
lt.LocalUpdate = &LocalUpdate{} lt.LocalUpdate = &LocalUpdate{}