diff --git a/db.go b/db.go index d62a2d7..4549a42 100644 --- a/db.go +++ b/db.go @@ -6,7 +6,7 @@ import ( "log" "time" - _ "github.com/mattn/go-sqlite3" + "github.com/mattn/go-sqlite3" ) type DB struct { @@ -21,7 +21,11 @@ func (db *DB) Open() error { return fmt.Errorf("database path not set") } - writeConn, err := sql.Open("sqlite3", db.path+"?_journal=WAL&_synchronous=NORMAL") + sql.Register("spellfixlite", &sqlite3.SQLiteDriver{ + Extensions: []string{"spellfix"}, + }) + + writeConn, err := sql.Open("spellfixlite", db.path+"?_journal=WAL&_synchronous=NORMAL") if err != nil { Error.Printf("%++v", err) return err @@ -31,7 +35,7 @@ func (db *DB) Open() error { writeConn.SetConnMaxLifetime(30 * time.Second) db.writeConn = writeConn - readConn, err := sql.Open("sqlite3", db.path+"?mode=ro&_journal=WAL&_synchronous=NORMAL&_mode=ro") + readConn, err := sql.Open("spellfixlite", db.path+"?mode=ro&_journal=WAL&_synchronous=NORMAL&_mode=ro") if err != nil { Error.Printf("%++v", err) return err @@ -79,7 +83,7 @@ func (db *DB) Init(ddl string) error { if _, ok := rows[table]; !ok { log.Printf("Table %s not found, initializing", table) needsInit = true - break; + break } } diff --git a/food.ddl b/food.ddl index 8e984e6..1352561 100644 --- a/food.ddl +++ b/food.ddl @@ -27,28 +27,28 @@ order by date desc; create view weightDaily as select strftime('%Y-%m-%d', date) as period, round(avg(weight), 2) as amount - from weight +from weight group by strftime('%Y-%m-%d', date) order by date desc; create view weightWeekly as select strftime('%Y-%W', date) as period, round(avg(weight), 2) as amount - from weight +from weight group by strftime('%Y-%W', date) order by date desc; create view weightMonthly as select strftime('%Y-%m', date) as period, round(avg(weight), 2) as amount - from weight +from weight group by strftime('%Y-%m', date) order by date desc; create view weightYearly as select strftime('%Y', date) as period, round(avg(weight), 2) as amount - from weight +from weight group by strftime('%Y', date) order by date desc; @@ -61,6 +61,80 @@ create table food( energy generated always as (coalesce(amount, 0) * coalesce(per100, 0) / 100) stored ); +create virtual table foodfix using spellfix1; +-- insert into foodfix (word, rank) +-- select food as word, +-- count(*) as rank +-- from food +-- group by food; +drop trigger if exists food_foodfix_insert; +create trigger food_foodfix_insert AFTER +insert on food for EACH row +begin +update foodfix +set rank = rank + 1 +where word = new.food; +insert into foodfix (word, rank) +select new.food, + 1 +where not exists ( + select 1 + from foodfix + where word = new.food + ); +end; + +drop trigger if exists food_foodfix_delete; +create trigger food_foodfix_delete AFTER +delete on food for EACH row +begin +update foodfix +set rank = rank - 1 +where word = old.food; + +delete from foodfix +where word = old.food + and rank <= 0; +end; + + +drop trigger if exists food_foodfix_update; +create trigger food_foodfix_update AFTER +update on food for EACH row +begin +update foodfix +set rank = rank - 1 +where word = old.food; + +delete from foodfix +where word = old.food + and rank <= 0; +update foodfix +set rank = rank + 1 +where word = new.food; + +insert into foodfix (word, rank) +select new.food, + 1 +where not exists ( + select 1 + from foodfix + where word = new.food + ); +end; + +-- Spellfix search example +with search_results as ( + select word, rank + from foodfix + where word MATCH 'B' + limit 1 +) +select f.*, s.rank +from search_results s + inner join food f on s.word = f.food +order by f.date desc; + create index dailyIdx on food(strftime('%Y-%m-%d', date)); create index weeklyIdx on food(strftime('%Y-%W', date)); create index monthlyIdx on food(strftime('%Y-%m', date)); @@ -134,17 +208,17 @@ insert on food begin update food set per100 = coalesce( - new .per100, + new.per100, ( select per100 from food - where food = new .food + where food = new.food and per100 is not null order by date desc limit 1 ) ) -where rowid = new .rowid; +where rowid = new.rowid; end; create table settings(