keep relevant local updates
This commit is contained in:
parent
ff86bab8ba
commit
41a27a4799
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{}
|
||||||
|
|
Loading…
Reference in New Issue