This commit is contained in:
Erik Winter 2024-10-24 07:29:32 +02:00
parent 575ff61fe4
commit 5bafda072b
3 changed files with 79 additions and 6 deletions

View File

@ -30,6 +30,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
fmt.Printf("%+v\n", conf)
syncClient := client.New(conf.SyncURL, conf.ApiKey) syncClient := client.New(conf.SyncURL, conf.ApiKey)
app := &cli.App{ app := &cli.App{

View File

@ -18,6 +18,13 @@ var migrations = []string{
`PRAGMA synchronous=NORMAL`, `PRAGMA synchronous=NORMAL`,
`PRAGMA cache_size=2000`, `PRAGMA cache_size=2000`,
`CREATE TABLE localids ("id" TEXT UNIQUE, "local_id" INTEGER)`, `CREATE TABLE localids ("id" TEXT UNIQUE, "local_id" INTEGER)`,
`CREATE TABLE items (
id TEXT PRIMARY KEY NOT NULL,
kind TEXT NOT NULL,
updated TIMESTAMP NOT NULL,
deleted BOOLEAN NOT NULL,
body TEXT NOT NULL
)`,
} }
var ( var (
@ -39,7 +46,9 @@ func NewSqlites(dbPath string) (*LocalID, *SqliteEvent, *SqliteSync, error) {
se := &SqliteEvent{ se := &SqliteEvent{
db: db, db: db,
} }
ss := &SqliteSync{} ss := &SqliteSync{
db: db,
}
if err := migrate(db, migrations); err != nil { if err := migrate(db, migrations); err != nil {
return nil, nil, nil, err return nil, nil, nil, err

View File

@ -1,29 +1,92 @@
package sqlite package sqlite
import ( import (
"database/sql"
"fmt"
"time" "time"
"go-mod.ewintr.nl/planner/item" "go-mod.ewintr.nl/planner/item"
) )
type SqliteSync struct{} type SqliteSync struct {
db *sql.DB
}
func NewSqliteSync() *SqliteSync { func NewSqliteSync(db *sql.DB) *SqliteSync {
return &SqliteSync{} return &SqliteSync{db: db}
} }
func (s *SqliteSync) FindAll() ([]item.Item, error) { func (s *SqliteSync) FindAll() ([]item.Item, error) {
return nil, nil rows, err := s.db.Query("SELECT id, kind, updated, deleted, body FROM items")
if err != nil {
return nil, fmt.Errorf("%w: failed to query items: %v", ErrSqliteFailure, err)
}
defer rows.Close()
var items []item.Item
for rows.Next() {
var i item.Item
var updatedStr string
err := rows.Scan(&i.ID, &i.Kind, &updatedStr, &i.Deleted, &i.Body)
if err != nil {
return nil, fmt.Errorf("%w: failed to scan item: %v", ErrSqliteFailure, err)
}
i.Updated, err = time.Parse(time.RFC3339, updatedStr)
if err != nil {
return nil, fmt.Errorf("%w: failed to parse updated time: %v", ErrSqliteFailure, err)
}
items = append(items, i)
}
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("%w: error iterating over rows: %v", ErrSqliteFailure, err)
}
return items, nil
} }
func (s *SqliteSync) Store(i item.Item) error { func (s *SqliteSync) Store(i item.Item) error {
// Ensure we have a valid time
if i.Updated.IsZero() {
i.Updated = time.Now()
}
_, err := s.db.Exec(
"INSERT OR REPLACE INTO items (id, kind, updated, deleted, body) VALUES (?, ?, ?, ?, ?)",
i.ID,
i.Kind,
i.Updated.UTC().Format(time.RFC3339),
i.Deleted,
sql.NullString{String: i.Body, Valid: i.Body != ""}, // This allows empty string but not NULL
)
if err != nil {
return fmt.Errorf("%w: failed to store item: %v", ErrSqliteFailure, err)
}
return nil return nil
} }
func (s *SqliteSync) DeleteAll() error { func (s *SqliteSync) DeleteAll() error {
_, err := s.db.Exec("DELETE FROM items")
if err != nil {
return fmt.Errorf("%w: failed to delete all items: %v", ErrSqliteFailure, err)
}
return nil return nil
} }
func (s *SqliteSync) LastUpdate() (time.Time, error) { func (s *SqliteSync) LastUpdate() (time.Time, error) {
return time.Time{}, nil var updatedStr sql.NullString
err := s.db.QueryRow("SELECT MAX(updated) FROM items").Scan(&updatedStr)
if 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)
if err != nil {
return time.Time{}, fmt.Errorf("%w: failed to parse last update time: %v", ErrSqliteFailure, err)
}
return lastUpdate, nil
} }