introduce local status

This commit is contained in:
Erik Winter 2021-09-01 06:52:21 +02:00
parent a2a0e9bb7b
commit 86ad6cb0fb
9 changed files with 64 additions and 73 deletions

View File

@ -21,7 +21,7 @@ func FormatTaskTable(tasks []*task.LocalTask) string {
var output string var output string
for _, t := range tasks { for _, t := range tasks {
var updateStr string var updateStr string
if t.LocalUpdate.ForVersion != 0 { if t.LocalStatus == task.STATUS_UPDATED {
updateStr = " *" updateStr = " *"
} }
output += fmt.Sprintf("%d%s\t%s\t%s (%s)\n", t.LocalId, updateStr, t.Due.String(), t.Action, t.Project) output += fmt.Sprintf("%d%s\t%s\t%s (%s)\n", t.LocalId, updateStr, t.Due.String(), t.Action, t.Project)

View File

@ -48,9 +48,9 @@ func TestListProcess(t *testing.T) {
Project: "project2", Project: "project2",
} }
allTasks := []*task.Task{task1, task2, task3, task4} allTasks := []*task.Task{task1, task2, task3, task4}
localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: &task.LocalUpdate{}} localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: &task.LocalUpdate{}, LocalStatus: task.STATUS_FETCHED}
localTask3 := &task.LocalTask{Task: *task3, LocalUpdate: &task.LocalUpdate{}} localTask3 := &task.LocalTask{Task: *task3, LocalUpdate: &task.LocalUpdate{}, LocalStatus: task.STATUS_FETCHED}
localTask4 := &task.LocalTask{Task: *task4, LocalUpdate: &task.LocalUpdate{}} localTask4 := &task.LocalTask{Task: *task4, LocalUpdate: &task.LocalUpdate{}, LocalStatus: task.STATUS_FETCHED}
local := storage.NewMemory() local := storage.NewMemory()
test.OK(t, local.SetTasks(allTasks)) test.OK(t, local.SetTasks(allTasks))

View File

@ -25,8 +25,8 @@ func TestSyncProcess(t *testing.T) {
Folder: task.FOLDER_UNPLANNED, Folder: task.FOLDER_UNPLANNED,
} }
localTask1 := &task.LocalTask{Task: *task1, LocalUpdate: &task.LocalUpdate{}} localTask1 := &task.LocalTask{Task: *task1, LocalUpdate: &task.LocalUpdate{}, LocalStatus: task.STATUS_FETCHED}
localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: &task.LocalUpdate{}} localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: &task.LocalUpdate{}, LocalStatus: task.STATUS_FETCHED}
mstorer, err := mstore.NewMemory(task.KnownFolders) mstorer, err := mstore.NewMemory(task.KnownFolders)
test.OK(t, err) test.OK(t, err)

View File

@ -72,8 +72,8 @@ func NextLocalId(used []int) int {
// MergeNewTaskSet updates a local set of tasks with a remote one // MergeNewTaskSet updates a local set of tasks with a remote one
// //
// New set is leading and tasks that are not in there get dismissed. Tasks that // The new set is leading and tasks that are not in there get dismissed. Tasks that
// were created locally and got dispatched might temporarily dissappear if the // were created locally and got dispatched might temporarily dissappear if the
// remote inbox has a delay in processing. // remote inbox has a delay in processing.
func MergeNewTaskSet(oldTasks []*task.LocalTask, newTasks []*task.Task) []*task.LocalTask { func MergeNewTaskSet(oldTasks []*task.LocalTask, newTasks []*task.Task) []*task.LocalTask {
@ -84,6 +84,7 @@ func MergeNewTaskSet(oldTasks []*task.LocalTask, newTasks []*task.Task) []*task.
Task: *nt, Task: *nt,
LocalId: 0, LocalId: 0,
LocalUpdate: &task.LocalUpdate{}, LocalUpdate: &task.LocalUpdate{},
LocalStatus: task.STATUS_FETCHED,
} }
} }
oldMap := map[string]*task.LocalTask{} oldMap := map[string]*task.LocalTask{}
@ -116,6 +117,7 @@ func MergeNewTaskSet(oldTasks []*task.LocalTask, newTasks []*task.Task) []*task.
if nt, ok := resultMap[ot.Id]; ok { if nt, ok := resultMap[ot.Id]; ok {
if ot.LocalUpdate.ForVersion >= nt.Version { if ot.LocalUpdate.ForVersion >= nt.Version {
resultMap[ot.Id].LocalUpdate = ot.LocalUpdate resultMap[ot.Id].LocalUpdate = ot.LocalUpdate
resultMap[ot.Id].LocalStatus = task.STATUS_UPDATED
} }
} }
} }

View File

@ -106,8 +106,8 @@ func TestMergeNewTaskSet(t *testing.T) {
oldTasks: []*task.LocalTask{}, oldTasks: []*task.LocalTask{},
newTasks: []*task.Task{task1, task2}, newTasks: []*task.Task{task1, task2},
exp: []*task.LocalTask{ exp: []*task.LocalTask{
{Task: *task1, LocalUpdate: emptyUpdate}, {Task: *task1, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
{Task: *task2, LocalUpdate: emptyUpdate}, {Task: *task2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
}, },
}, },
{ {
@ -118,8 +118,8 @@ func TestMergeNewTaskSet(t *testing.T) {
}, },
newTasks: []*task.Task{task1v2, task2}, newTasks: []*task.Task{task1v2, task2},
exp: []*task.LocalTask{ exp: []*task.LocalTask{
{Task: *task1v2, LocalUpdate: emptyUpdate}, {Task: *task1v2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
{Task: *task2, LocalUpdate: emptyUpdate}, {Task: *task2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
}, },
}, },
{ {
@ -130,7 +130,7 @@ func TestMergeNewTaskSet(t *testing.T) {
}, },
newTasks: []*task.Task{task2}, newTasks: []*task.Task{task2},
exp: []*task.LocalTask{ exp: []*task.LocalTask{
{Task: *task2, LocalUpdate: emptyUpdate}, {Task: *task2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
}, },
}, },
{ {
@ -153,13 +153,14 @@ func TestMergeNewTaskSet(t *testing.T) {
}, },
newTasks: []*task.Task{task1v2, task2}, newTasks: []*task.Task{task1v2, task2},
exp: []*task.LocalTask{ exp: []*task.LocalTask{
{Task: *task1v2, LocalUpdate: emptyUpdate}, {Task: *task1v2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED},
{ {
Task: *task2, Task: *task2,
LocalUpdate: &task.LocalUpdate{ LocalUpdate: &task.LocalUpdate{
ForVersion: 2, ForVersion: 2,
Project: "project-v3", Project: "project-v3",
}, },
LocalStatus: task.STATUS_UPDATED,
}, },
}, },
}, },

View File

@ -43,9 +43,9 @@ func TestMemory(t *testing.T) {
} }
tasks := []*task.Task{task1, task2, task3} tasks := []*task.Task{task1, task2, task3}
emptyUpdate := &task.LocalUpdate{} emptyUpdate := &task.LocalUpdate{}
localTask1 := &task.LocalTask{Task: *task1, LocalUpdate: emptyUpdate} localTask1 := &task.LocalTask{Task: *task1, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED}
localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: emptyUpdate} localTask2 := &task.LocalTask{Task: *task2, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED}
localTask3 := &task.LocalTask{Task: *task3, LocalUpdate: emptyUpdate} localTask3 := &task.LocalTask{Task: *task3, LocalUpdate: emptyUpdate, LocalStatus: task.STATUS_FETCHED}
t.Run("sync", func(t *testing.T) { t.Run("sync", func(t *testing.T) {
mem := storage.NewMemory() mem := storage.NewMemory()

View File

@ -24,6 +24,8 @@ var sqliteMigrations = []sqliteMigration{
`UPDATE task SET local_id = (SELECT local_id FROM local_task WHERE local_task.id=task.id)`, `UPDATE task SET local_id = (SELECT local_id FROM local_task WHERE local_task.id=task.id)`,
`UPDATE task SET local_update = (SELECT local_update FROM local_task WHERE local_task.id=task.id)`, `UPDATE task SET local_update = (SELECT local_update FROM local_task WHERE local_task.id=task.id)`,
`DROP TABLE local_task`, `DROP TABLE local_task`,
`ALTER TABLE task ADD COLUMN local_status TEXT`,
`UPDATE task SET local_status = "fetched"`,
} }
var ( var (
@ -93,10 +95,10 @@ func (s *Sqlite) SetTasks(tasks []*task.Task) error {
_, err := s.db.Exec(` _, err := s.db.Exec(`
INSERT INTO task INSERT INTO task
(id, local_id, version, folder, action, project, due, recur, local_update) (id, local_id, version, folder, action, project, due, recur, local_update, local_status)
VALUES VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?)`, (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
t.Id, t.LocalId, t.Version, t.Folder, t.Action, t.Project, t.Due.String(), recurStr, t.LocalUpdate) t.Id, t.LocalId, t.Version, t.Folder, t.Action, t.Project, t.Due.String(), recurStr, t.LocalUpdate, t.LocalStatus)
if err != nil { if err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
@ -108,25 +110,50 @@ VALUES
func (s *Sqlite) FindAll() ([]*task.LocalTask, error) { func (s *Sqlite) FindAll() ([]*task.LocalTask, error) {
rows, err := s.db.Query(` rows, err := s.db.Query(`
SELECT id, local_id, version, folder, action, project, due, recur, local_update SELECT id, local_id, version, folder, action, project, due, recur, local_update, local_status
FROM task`) FROM task`)
if err != nil { if err != nil {
return []*task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return []*task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
return tasksFromRows(rows) tasks := []*task.LocalTask{}
defer rows.Close()
for rows.Next() {
var id, folder, action, project, due, recur, localStatus string
var localId, version int
var localUpdate task.LocalUpdate
if err := rows.Scan(&id, &localId, &version, &folder, &action, &project, &due, &recur, &localUpdate, &localStatus); err != nil {
return []*task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
tasks = append(tasks, &task.LocalTask{
Task: task.Task{
Id: id,
Version: version,
Folder: folder,
Action: action,
Project: project,
Due: task.NewDateFromString(due),
Recur: task.NewRecurrer(recur),
},
LocalId: localId,
LocalUpdate: &localUpdate,
LocalStatus: localStatus,
})
}
return tasks, nil
} }
func (s *Sqlite) FindById(id string) (*task.LocalTask, error) { func (s *Sqlite) FindById(id string) (*task.LocalTask, error) {
var folder, action, project, due, recur string var folder, action, project, due, recur, localStatus string
var localId, version int var localId, version int
var localUpdate task.LocalUpdate var localUpdate task.LocalUpdate
row := s.db.QueryRow(` row := s.db.QueryRow(`
SELECT local_id, version, folder, action, project, due, recur, local_update SELECT local_id, version, folder, action, project, due, recur, local_update, local_status
FROM task FROM task
WHERE task.id = ? WHERE task.id = ?
LIMIT 1`, id) LIMIT 1`, id)
if err := row.Scan(&localId, &version, &folder, &action, &project, &due, &recur, &localUpdate); err != nil { if err := row.Scan(&localId, &version, &folder, &action, &project, &due, &recur, &localUpdate, &localStatus); err != nil {
return &task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return &task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
@ -142,6 +169,7 @@ LIMIT 1`, id)
}, },
LocalId: localId, LocalId: localId,
LocalUpdate: &localUpdate, LocalUpdate: &localUpdate,
LocalStatus: localStatus,
}, nil }, nil
} }
@ -163,43 +191,14 @@ func (s *Sqlite) FindByLocalId(localId int) (*task.LocalTask, error) {
func (s *Sqlite) SetLocalUpdate(tsk *task.LocalTask) error { func (s *Sqlite) SetLocalUpdate(tsk *task.LocalTask) error {
if _, err := s.db.Exec(` if _, err := s.db.Exec(`
UPDATE task UPDATE task
SET local_update = ? SET local_update = ?, local_status = ?
WHERE local_id = ?`, tsk.LocalUpdate, tsk.LocalId); err != nil { WHERE local_id = ?`, tsk.LocalUpdate, task.STATUS_UPDATED, tsk.LocalId); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
return nil return nil
} }
func tasksFromRows(rows *sql.Rows) ([]*task.LocalTask, error) {
tasks := []*task.LocalTask{}
defer rows.Close()
for rows.Next() {
var id, folder, action, project, due, recur string
var localId, version int
var localUpdate task.LocalUpdate
if err := rows.Scan(&id, &localId, &version, &folder, &action, &project, &due, &recur, &localUpdate); err != nil {
return []*task.LocalTask{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
tasks = append(tasks, &task.LocalTask{
Task: task.Task{
Id: id,
Version: version,
Folder: folder,
Action: action,
Project: project,
Due: task.NewDateFromString(due),
Recur: task.NewRecurrer(recur),
},
LocalId: localId,
LocalUpdate: &localUpdate,
})
}
return tasks, nil
}
func (s *Sqlite) migrate(wanted []sqliteMigration) error { func (s *Sqlite) migrate(wanted []sqliteMigration) error {
// admin table // admin table
if _, err := s.db.Exec(` if _, err := s.db.Exec(`

View File

@ -7,10 +7,16 @@ import (
"strings" "strings"
) )
const (
STATUS_FETCHED = "fetched"
STATUS_UPDATED = "updated"
)
type LocalTask struct { type LocalTask struct {
Task Task
LocalId int LocalId int
LocalUpdate *LocalUpdate LocalUpdate *LocalUpdate
LocalStatus string
} }
func (lt *LocalTask) HasUpdate() bool { func (lt *LocalTask) HasUpdate() bool {

View File

@ -2,7 +2,6 @@ package mstore
import ( import (
"errors" "errors"
"fmt"
) )
var ( var (
@ -25,29 +24,13 @@ func (m *Message) Valid() bool {
} }
func (m *Message) Equal(n *Message) bool { func (m *Message) Equal(n *Message) bool {
var prt bool
if m.Uid == 156 && n.Uid == 155 {
prt = true
}
if m.Uid == 155 && n.Uid == 156 {
prt = true
}
if m.Folder != n.Folder { if m.Folder != n.Folder {
if prt {
fmt.Println("folder")
}
return false return false
} }
if m.Subject != n.Subject { if m.Subject != n.Subject {
if prt {
fmt.Println("subject")
}
return false return false
} }
if m.Body != n.Body { if m.Body != n.Body {
if prt {
fmt.Println("body")
}
return false return false
} }