done
This commit is contained in:
parent
575ff61fe4
commit
5bafda072b
|
@ -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{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue