package db0305 import ( "encoding/json" "errors" ) type DB struct { KV KV tables map[string]Schema } func (db *DB) Open() error { db.tables = map[string]Schema{} return db.KV.Open() } func (db *DB) Close() error { return db.KV.Close() } func (db *DB) Select(schema *Schema, row Row) (ok bool, err error) { key := row.EncodeKey(schema) val, ok, err := db.KV.Get(key) if err != nil || !ok { return ok, err } if err = row.DecodeVal(schema, val); err != nil { return false, err } return true, nil } func (db *DB) Insert(schema *Schema, row Row) (updated bool, err error) { key := row.EncodeKey(schema) val := row.EncodeVal(schema) return db.KV.SetEx(key, val, ModeInsert) } func (db *DB) Upsert(schema *Schema, row Row) (updated bool, err error) { key := row.EncodeKey(schema) val := row.EncodeVal(schema) return db.KV.SetEx(key, val, ModeUpsert) } func (db *DB) Update(schema *Schema, row Row) (updated bool, err error) { key := row.EncodeKey(schema) val := row.EncodeVal(schema) return db.KV.SetEx(key, val, ModeUpdate) } func (db *DB) Delete(schema *Schema, row Row) (deleted bool, err error) { key := row.EncodeKey(schema) return db.KV.Del(key) } type SQLResult struct { Updated int Header []string Values []Row } func (db *DB) ExecStmt(stmt interface{}) (r SQLResult, err error) { switch ptr := stmt.(type) { case *StmtCreatTable: err = db.execCreateTable(ptr) case *StmtSelect: r.Header = ptr.cols r.Values, err = db.execSelect(ptr) case *StmtInsert: r.Updated, err = db.execInsert(ptr) case *StmtUpdate: r.Updated, err = db.execUpdate(ptr) case *StmtDelete: r.Updated, err = db.execDelete(ptr) default: panic("unreachable") } return } func (db *DB) execCreateTable(stmt *StmtCreatTable) (err error) func (db *DB) GetSchema(table string) (Schema, error) { schema, ok := db.tables[table] if !ok { val, ok, err := db.KV.Get([]byte("@schema_" + table)) if err == nil && ok { err = json.Unmarshal(val, &schema) } if err != nil { return Schema{}, err } if !ok { return Schema{}, errors.New("table is not found") } db.tables[table] = schema } return schema, nil } func (db *DB) execSelect(stmt *StmtSelect) ([]Row, error) func (db *DB) execInsert(stmt *StmtInsert) (count int, err error) func (db *DB) execUpdate(stmt *StmtUpdate) (count int, err error) func (db *DB) execDelete(stmt *StmtDelete) (count int, err error) // QzBQWVJJOUhU https://trialofcode.org/