Update to work with sql parser improvements
This commit is contained in:
parent
fe7ab7019c
commit
a0d3f6ec2a
11 changed files with 467 additions and 194 deletions
58
db/create.go
58
db/create.go
|
@ -22,33 +22,41 @@ import (
|
|||
"github.com/abcum/surreal/util/uuid"
|
||||
)
|
||||
|
||||
func executeCreateStatement(ast *sql.CreateStatement) (out []interface{}, err error) {
|
||||
func executeCreateStatement(txn kvs.TX, ast *sql.CreateStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, w := range ast.What {
|
||||
|
||||
if what, ok := w.(*sql.Thing); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: what.ID}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, key)
|
||||
if ret, err := create(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := create(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
}
|
||||
}
|
||||
|
||||
if what, ok := w.(sql.Table); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what, ID: uuid.NewV5(uuid.NewV4().UUID, ast.KV).String()}
|
||||
if what, ok := w.(*sql.Table); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: uuid.NewV5(uuid.NewV4().UUID, ast.KV).String()}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, key)
|
||||
if ret, err := create(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := create(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
|
@ -57,32 +65,34 @@ func executeCreateStatement(ast *sql.CreateStatement) (out []interface{}, err er
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func create(txn kvs.TX, doc *item.Doc, ast *sql.CreateStatement) (out interface{}, err error) {
|
||||
func create(doc *item.Doc, ast *sql.CreateStatement) (out interface{}, err error) {
|
||||
|
||||
if !doc.Allow(txn, "create") {
|
||||
if err = doc.Merge(ast.Data); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !doc.Allow("CREATE") {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err = doc.Merge(txn, ast.Data); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StoreIndex(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StoreIndex(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StartThing(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StartThing(txn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = doc.StorePatch(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StorePatch(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = doc.Yield(ast.Echo, sql.AFTER)
|
||||
|
|
68
db/db.go
68
db/db.go
|
@ -63,6 +63,8 @@ func Exit() {
|
|||
// Prepare prepares a query for parameterization for future execution
|
||||
func Prepare(sql string, param ...interface{}) string {
|
||||
|
||||
// IMPORTANT Need to improve database paramaterization
|
||||
|
||||
return fmt.Sprintf(sql, param...)
|
||||
|
||||
}
|
||||
|
@ -120,7 +122,12 @@ func detail(e error) interface{} {
|
|||
|
||||
func execute(ctx *fibre.Context, ast *sql.Query, chn chan<- interface{}) {
|
||||
|
||||
var txn kvs.TX
|
||||
|
||||
defer func() {
|
||||
if txn != nil {
|
||||
txn.Rollback()
|
||||
}
|
||||
if r := recover(); r != nil {
|
||||
if err, ok := r.(error); ok {
|
||||
fmt.Printf("%s", debug.Stack())
|
||||
|
@ -143,37 +150,70 @@ func execute(ctx *fibre.Context, ast *sql.Query, chn chan<- interface{}) {
|
|||
continue
|
||||
|
||||
case *sql.SelectStatement:
|
||||
res, err = executeSelectStatement(stm)
|
||||
res, err = executeSelectStatement(txn, stm)
|
||||
case *sql.CreateStatement:
|
||||
res, err = executeCreateStatement(stm)
|
||||
res, err = executeCreateStatement(txn, stm)
|
||||
case *sql.UpdateStatement:
|
||||
res, err = executeUpdateStatement(stm)
|
||||
res, err = executeUpdateStatement(txn, stm)
|
||||
case *sql.ModifyStatement:
|
||||
res, err = executeModifyStatement(stm)
|
||||
res, err = executeModifyStatement(txn, stm)
|
||||
case *sql.DeleteStatement:
|
||||
res, err = executeDeleteStatement(stm)
|
||||
res, err = executeDeleteStatement(txn, stm)
|
||||
case *sql.RelateStatement:
|
||||
res, err = executeRelateStatement(stm)
|
||||
res, err = executeRelateStatement(txn, stm)
|
||||
case *sql.RecordStatement:
|
||||
res, err = executeRecordStatement(stm)
|
||||
res, err = executeRecordStatement(txn, stm)
|
||||
|
||||
case *sql.DefineRulesStatement:
|
||||
res, err = executeDefineRulesStatement(txn, stm)
|
||||
case *sql.RemoveRulesStatement:
|
||||
res, err = executeRemoveRulesStatement(txn, stm)
|
||||
|
||||
case *sql.DefineTableStatement:
|
||||
res, err = executeDefineTableStatement(stm)
|
||||
res, err = executeDefineTableStatement(txn, stm)
|
||||
case *sql.RemoveTableStatement:
|
||||
res, err = executeRemoveTableStatement(stm)
|
||||
res, err = executeRemoveTableStatement(txn, stm)
|
||||
|
||||
case *sql.DefineFieldStatement:
|
||||
res, err = executeDefineFieldStatement(stm)
|
||||
res, err = executeDefineFieldStatement(txn, stm)
|
||||
case *sql.RemoveFieldStatement:
|
||||
res, err = executeRemoveFieldStatement(stm)
|
||||
res, err = executeRemoveFieldStatement(txn, stm)
|
||||
|
||||
case *sql.DefineIndexStatement:
|
||||
res, err = executeDefineIndexStatement(stm)
|
||||
res, err = executeDefineIndexStatement(txn, stm)
|
||||
case *sql.ResyncIndexStatement:
|
||||
res, err = executeResyncIndexStatement(stm)
|
||||
res, err = executeResyncIndexStatement(txn, stm)
|
||||
case *sql.RemoveIndexStatement:
|
||||
res, err = executeRemoveIndexStatement(stm)
|
||||
res, err = executeRemoveIndexStatement(txn, stm)
|
||||
|
||||
case *sql.BeginStatement:
|
||||
if txn != nil {
|
||||
chn <- fibre.NewHTTPError(400, "Transaction already running")
|
||||
return
|
||||
} else if txn, err = db.Txn(true); err != nil {
|
||||
chn <- err
|
||||
return
|
||||
}
|
||||
|
||||
case *sql.CommitStatement:
|
||||
if txn != nil {
|
||||
txn.Commit()
|
||||
txn = nil
|
||||
continue
|
||||
}
|
||||
|
||||
case *sql.CancelStatement:
|
||||
if txn != nil {
|
||||
txn.Rollback()
|
||||
txn = nil
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err != nil && txn != nil {
|
||||
txn.Rollback()
|
||||
chn <- err
|
||||
}
|
||||
|
||||
chn <- &Response{
|
||||
|
|
147
db/define.go
147
db/define.go
|
@ -15,19 +15,28 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/kvs"
|
||||
"github.com/abcum/surreal/sql"
|
||||
"github.com/abcum/surreal/util/data"
|
||||
"github.com/abcum/surreal/util/keys"
|
||||
"github.com/abcum/surreal/util/pack"
|
||||
)
|
||||
|
||||
func executeDefineTableStatement(ast *sql.DefineTableStatement) (out []interface{}, err error) {
|
||||
func executeDefineTableStatement(txn kvs.TX, ast *sql.DefineTableStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -45,34 +54,81 @@ func executeDefineTableStatement(ast *sql.DefineTableStatement) (out []interface
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeDefineFieldStatement(ast *sql.DefineFieldStatement) (out []interface{}, err error) {
|
||||
func executeDefineRulesStatement(txn kvs.TX, ast *sql.DefineRulesStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
doc := data.New()
|
||||
doc.Set(ast.Name, "name")
|
||||
doc.Set(ast.Type, "type")
|
||||
doc.Set(ast.Enum, "enum")
|
||||
doc.Set(ast.Code, "code")
|
||||
doc.Set(ast.Min, "min")
|
||||
doc.Set(ast.Max, "max")
|
||||
doc.Set(ast.Match, "match")
|
||||
doc.Set(ast.Default, "default")
|
||||
doc.Set(ast.Notnull, "notnull")
|
||||
doc.Set(ast.Readonly, "readonly")
|
||||
doc.Set(ast.Mandatory, "mandatory")
|
||||
doc.Set(ast.Validate, "validate")
|
||||
for _, TB := range ast.What {
|
||||
|
||||
for _, RU := range ast.When {
|
||||
|
||||
// Set the database definition
|
||||
dkey := &keys.DB{KV: ast.KV, NS: ast.NS, DB: ast.DB}
|
||||
if err := txn.Put(dkey.Encode(), nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the table definition
|
||||
tkey := &keys.TB{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB}
|
||||
if err := txn.Put(tkey.Encode(), nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the field definition
|
||||
rkey := &keys.RU{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, RU: RU}
|
||||
if err := txn.Put(rkey.Encode(), pack.ToPACK(ast)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeDefineFieldStatement(txn kvs.TX, ast *sql.DefineFieldStatement) (out []interface{}, err error) {
|
||||
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -90,37 +146,36 @@ func executeDefineFieldStatement(ast *sql.DefineFieldStatement) (out []interface
|
|||
|
||||
// Set the field definition
|
||||
fkey := &keys.FD{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, FD: ast.Name}
|
||||
if err := txn.Put(fkey.Encode(), doc.ToPACK()); err != nil {
|
||||
if err := txn.Put(fkey.Encode(), pack.ToPACK(ast)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeDefineIndexStatement(ast *sql.DefineIndexStatement) (out []interface{}, err error) {
|
||||
func executeDefineIndexStatement(txn kvs.TX, ast *sql.DefineIndexStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
|
||||
doc := data.New()
|
||||
// doc.Set(ast.Name, "name")
|
||||
// doc.Set(ast.Type, "type")
|
||||
// doc.Set(ast.Code, "code")
|
||||
// doc.Set(ast.Min, "min")
|
||||
// doc.Set(ast.Max, "max")
|
||||
// doc.Set(ast.Default, "default")
|
||||
// doc.Set(ast.Notnull, "notnull")
|
||||
// doc.Set(ast.Readonly, "readonly")
|
||||
// doc.Set(ast.Mandatory, "mandatory")
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -138,13 +193,15 @@ func executeDefineIndexStatement(ast *sql.DefineIndexStatement) (out []interface
|
|||
|
||||
// Set the index definition
|
||||
ikey := &keys.IX{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, IX: ast.Name}
|
||||
if err := txn.Put(ikey.Encode(), doc.ToPACK()); err != nil {
|
||||
if err := txn.Put(ikey.Encode(), pack.ToPACK(ast)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
|
|
62
db/delete.go
62
db/delete.go
|
@ -21,35 +21,43 @@ import (
|
|||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeDeleteStatement(ast *sql.DeleteStatement) (out []interface{}, err error) {
|
||||
func executeDeleteStatement(txn kvs.TX, ast *sql.DeleteStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, w := range ast.What {
|
||||
|
||||
if what, ok := w.(*sql.Thing); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: what.ID}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, key)
|
||||
if ret, err := delete(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := delete(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
}
|
||||
}
|
||||
|
||||
if what, ok := w.(sql.Table); ok {
|
||||
beg := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what, ID: keys.Prefix}
|
||||
end := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what, ID: keys.Suffix}
|
||||
if what, ok := w.(*sql.Table); ok {
|
||||
beg := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Prefix}
|
||||
end := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Suffix}
|
||||
kvs, _ := txn.RGet(beg.Encode(), end.Encode(), 0)
|
||||
for _, kv := range kvs {
|
||||
doc := item.New(kv, nil)
|
||||
if ret, err := delete(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, nil)
|
||||
if ret, err := delete(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
|
@ -59,38 +67,40 @@ func executeDeleteStatement(ast *sql.DeleteStatement) (out []interface{}, err er
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func delete(txn kvs.TX, doc *item.Doc, ast *sql.DeleteStatement) (out interface{}, err error) {
|
||||
func delete(doc *item.Doc, ast *sql.DeleteStatement) (out interface{}, err error) {
|
||||
|
||||
if !doc.Allow(txn, "delete") {
|
||||
return nil, nil
|
||||
if !doc.Allow("DELETE") {
|
||||
return
|
||||
}
|
||||
|
||||
if !doc.Check(txn, ast.Cond) {
|
||||
return nil, nil
|
||||
if !doc.Check(ast.Cond) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.Erase(txn, nil); err != nil {
|
||||
return nil, err
|
||||
if err = doc.Erase(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.PurgeIndex(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.PurgeIndex(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.PurgeThing(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.PurgeThing(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if ast.Hard {
|
||||
|
||||
if err = doc.PurgePatch(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.PurgePatch(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
|
52
db/modify.go
52
db/modify.go
|
@ -21,22 +21,30 @@ import (
|
|||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeModifyStatement(ast *sql.ModifyStatement) (out []interface{}, err error) {
|
||||
func executeModifyStatement(txn kvs.TX, ast *sql.ModifyStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, w := range ast.What {
|
||||
|
||||
if what, ok := w.(*sql.Thing); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: what.ID}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, key)
|
||||
if ret, err := modify(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := modify(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
|
@ -45,36 +53,38 @@ func executeModifyStatement(ast *sql.ModifyStatement) (out []interface{}, err er
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func modify(txn kvs.TX, doc *item.Doc, ast *sql.ModifyStatement) (out interface{}, err error) {
|
||||
func modify(doc *item.Doc, ast *sql.ModifyStatement) (out interface{}, err error) {
|
||||
|
||||
if !doc.Allow(txn, "modify") {
|
||||
return nil, nil
|
||||
if !doc.Allow("UPDATE") {
|
||||
return
|
||||
}
|
||||
|
||||
if !doc.Check(txn, ast.Cond) {
|
||||
return nil, nil
|
||||
if !doc.Check(ast.Cond) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.Merge(txn, ast.Diff); err != nil {
|
||||
return nil, err
|
||||
if err = doc.Merge(ast.Diff); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StoreIndex(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StoreIndex(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StoreThing(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StoreThing(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StorePatch(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StorePatch(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = doc.Yield(ast.Echo, sql.DIFF)
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/kvs"
|
||||
"github.com/abcum/surreal/sql"
|
||||
)
|
||||
|
||||
func executeRecordStatement(ast *sql.RecordStatement) ([]interface{}, error) {
|
||||
func executeRecordStatement(txn kvs.TX, ast *sql.RecordStatement) ([]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/kvs"
|
||||
"github.com/abcum/surreal/sql"
|
||||
)
|
||||
|
||||
func executeRelateStatement(ast *sql.RelateStatement) ([]interface{}, error) {
|
||||
func executeRelateStatement(txn kvs.TX, ast *sql.RelateStatement) ([]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
112
db/remove.go
112
db/remove.go
|
@ -15,18 +15,27 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/kvs"
|
||||
"github.com/abcum/surreal/sql"
|
||||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeRemoveTableStatement(ast *sql.RemoveTableStatement) (out []interface{}, err error) {
|
||||
func executeRemoveTableStatement(txn kvs.TX, ast *sql.RemoveTableStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -36,6 +45,12 @@ func executeRemoveTableStatement(ast *sql.RemoveTableStatement) (out []interface
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Remove the rules config
|
||||
rkey := &keys.RU{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, RU: keys.Ignore}
|
||||
if err := txn.PDel(rkey.Encode()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remove the field config
|
||||
fkey := &keys.FD{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, FD: keys.Ignore}
|
||||
if err := txn.PDel(fkey.Encode()); err != nil {
|
||||
|
@ -56,20 +71,69 @@ func executeRemoveTableStatement(ast *sql.RemoveTableStatement) (out []interface
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeRemoveFieldStatement(ast *sql.RemoveFieldStatement) (out []interface{}, err error) {
|
||||
func executeRemoveRulesStatement(txn kvs.TX, ast *sql.RemoveRulesStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
for _, RU := range ast.When {
|
||||
|
||||
// Remove the rules config
|
||||
ckey := &keys.RU{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, RU: RU}
|
||||
if err := txn.Del(ckey.Encode()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeRemoveFieldStatement(txn kvs.TX, ast *sql.RemoveFieldStatement) (out []interface{}, err error) {
|
||||
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -81,20 +145,30 @@ func executeRemoveFieldStatement(ast *sql.RemoveFieldStatement) (out []interface
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func executeRemoveIndexStatement(ast *sql.RemoveIndexStatement) (out []interface{}, err error) {
|
||||
func executeRemoveIndexStatement(txn kvs.TX, ast *sql.RemoveIndexStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -112,7 +186,9 @@ func executeRemoveIndexStatement(ast *sql.RemoveIndexStatement) (out []interface
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
|
|
29
db/resync.go
29
db/resync.go
|
@ -21,14 +21,21 @@ import (
|
|||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeResyncIndexStatement(ast *sql.ResyncIndexStatement) (out []interface{}, err error) {
|
||||
func executeResyncIndexStatement(txn kvs.TX, ast *sql.ResyncIndexStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, TB := range ast.What {
|
||||
|
||||
|
@ -44,23 +51,25 @@ func executeResyncIndexStatement(ast *sql.ResyncIndexStatement) (out []interface
|
|||
iend := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, ID: keys.Suffix}
|
||||
kvs, _ := txn.RGet(ibeg.Encode(), iend.Encode(), 0)
|
||||
for _, kv := range kvs {
|
||||
doc := item.New(kv, nil)
|
||||
if err := resync(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, nil)
|
||||
if err := resync(doc, ast); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func resync(txn kvs.TX, doc *item.Doc, ast *sql.ResyncIndexStatement) (err error) {
|
||||
func resync(doc *item.Doc, ast *sql.ResyncIndexStatement) (err error) {
|
||||
|
||||
if err = doc.StoreIndex(txn); err != nil {
|
||||
if err = doc.StoreIndex(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
65
db/select.go
65
db/select.go
|
@ -15,22 +15,71 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/kvs"
|
||||
"github.com/abcum/surreal/sql"
|
||||
"github.com/abcum/surreal/util/data"
|
||||
"github.com/abcum/surreal/util/item"
|
||||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeSelectStatement(ast *sql.SelectStatement) (out []interface{}, err error) {
|
||||
func executeSelectStatement(txn kvs.TX, ast *sql.SelectStatement) (out []interface{}, err error) {
|
||||
|
||||
kvs, err := db.All()
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
for _, kv := range kvs {
|
||||
if txn == nil {
|
||||
txn, err = db.Txn(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Close()
|
||||
}
|
||||
|
||||
for _, w := range ast.What {
|
||||
|
||||
if what, ok := w.(*sql.Thing); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: what.ID}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := detect(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
}
|
||||
}
|
||||
|
||||
if what, ok := w.(*sql.Table); ok {
|
||||
beg := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Prefix}
|
||||
end := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Suffix}
|
||||
kvs, _ := txn.RGet(beg.Encode(), end.Encode(), 0)
|
||||
for _, kv := range kvs {
|
||||
doc := item.New(kv, txn, nil)
|
||||
if ret, err := detect(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, map[string]interface{}{
|
||||
"key": string(kv.Key()),
|
||||
"val": data.NewFromPACK(kv.Val()).Data(),
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func detect(doc *item.Doc, ast *sql.SelectStatement) (out interface{}, err error) {
|
||||
|
||||
if !doc.Allow("SELECT") {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if !doc.Check(ast.Cond) {
|
||||
return
|
||||
}
|
||||
|
||||
out = doc.Blaze(ast)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
|
62
db/update.go
62
db/update.go
|
@ -21,35 +21,43 @@ import (
|
|||
"github.com/abcum/surreal/util/keys"
|
||||
)
|
||||
|
||||
func executeUpdateStatement(ast *sql.UpdateStatement) (out []interface{}, err error) {
|
||||
func executeUpdateStatement(txn kvs.TX, ast *sql.UpdateStatement) (out []interface{}, err error) {
|
||||
|
||||
txn, err := db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
var local bool
|
||||
|
||||
if ast.EX {
|
||||
return append(out, ast), nil
|
||||
}
|
||||
|
||||
defer txn.Rollback()
|
||||
if txn == nil {
|
||||
local = true
|
||||
txn, err = db.Txn(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer txn.Rollback()
|
||||
}
|
||||
|
||||
for _, w := range ast.What {
|
||||
|
||||
if what, ok := w.(*sql.Thing); ok {
|
||||
key := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: what.ID}
|
||||
kv, _ := txn.Get(key.Encode())
|
||||
doc := item.New(kv, key)
|
||||
if ret, err := update(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, key)
|
||||
if ret, err := update(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
}
|
||||
}
|
||||
|
||||
if what, ok := w.(sql.Table); ok {
|
||||
beg := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what, ID: keys.Prefix}
|
||||
end := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what, ID: keys.Suffix}
|
||||
if what, ok := w.(*sql.Table); ok {
|
||||
beg := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Prefix}
|
||||
end := &keys.Thing{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: what.TB, ID: keys.Suffix}
|
||||
kvs, _ := txn.RGet(beg.Encode(), end.Encode(), 0)
|
||||
for _, kv := range kvs {
|
||||
doc := item.New(kv, nil)
|
||||
if ret, err := update(txn, doc, ast); err != nil {
|
||||
doc := item.New(kv, txn, nil)
|
||||
if ret, err := update(doc, ast); err != nil {
|
||||
return nil, err
|
||||
} else if ret != nil {
|
||||
out = append(out, ret)
|
||||
|
@ -59,36 +67,38 @@ func executeUpdateStatement(ast *sql.UpdateStatement) (out []interface{}, err er
|
|||
|
||||
}
|
||||
|
||||
txn.Commit()
|
||||
if local {
|
||||
txn.Commit()
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func update(txn kvs.TX, doc *item.Doc, ast *sql.UpdateStatement) (out interface{}, err error) {
|
||||
func update(doc *item.Doc, ast *sql.UpdateStatement) (out interface{}, err error) {
|
||||
|
||||
if !doc.Allow(txn, "update") {
|
||||
return nil, nil
|
||||
if !doc.Allow("UPDATE") {
|
||||
return
|
||||
}
|
||||
|
||||
if !doc.Check(txn, ast.Cond) {
|
||||
return nil, nil
|
||||
if !doc.Check(ast.Cond) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.Merge(txn, ast.Data); err != nil {
|
||||
return nil, err
|
||||
if err = doc.Merge(ast.Data); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StoreIndex(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StoreIndex(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StoreThing(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StoreThing(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = doc.StorePatch(txn); err != nil {
|
||||
return nil, err
|
||||
if err = doc.StorePatch(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = doc.Yield(ast.Echo, sql.AFTER)
|
||||
|
|
Loading…
Reference in a new issue