Adding the challenge 0305
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
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/
|
||||
Reference in New Issue
Block a user