Improve database speed

This commit is contained in:
Tobie Morgan Hitchcock 2019-11-20 13:20:27 +00:00
parent 2e1b699a87
commit d0d566bbd9
59 changed files with 8692 additions and 13528 deletions

View file

@ -51,6 +51,6 @@ func init() {
// Init runs the cli app
func Init() {
if err := mainCmd.Execute(); err != nil {
os.Exit(-1)
os.Exit(1)
}
}

View file

@ -18,6 +18,7 @@ import (
"github.com/spf13/cobra"
"github.com/abcum/surreal/db"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/log"
"github.com/abcum/surreal/web"
)
@ -26,12 +27,15 @@ var startCmd = &cobra.Command{
Use: "start [flags]",
Short: "Start the database and http server",
PreRun: func(cmd *cobra.Command, args []string) {
log.Display(logo)
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
if err = kvs.Setup(opts); err != nil {
log.Fatal(err)
return
}
if err = db.Setup(opts); err != nil {
log.Fatal(err)
return
@ -47,12 +51,17 @@ var startCmd = &cobra.Command{
},
PostRunE: func(cmd *cobra.Command, args []string) (err error) {
if err = web.Exit(); err != nil {
if err = web.Exit(opts); err != nil {
log.Fatal(err)
return
}
if err = db.Exit(); err != nil {
if err = db.Exit(opts); err != nil {
log.Fatal(err)
return
}
if err = kvs.Exit(opts); err != nil {
log.Fatal(err)
return
}

View file

@ -15,34 +15,44 @@
package db
import (
"sync"
"github.com/dgraph-io/ristretto"
)
type cache struct {
items sync.Map
}
var keyCache *ristretto.Cache
var valCache *ristretto.Cache
func (c *cache) Clr() {
c.items.Range(func(key interface{}, _ interface{}) bool {
c.items.Delete(key)
return true
func init() {
keyCache, _ = ristretto.NewCache(&ristretto.Config{
NumCounters: 1e7,
MaxCost: 1 << 32,
BufferItems: 64,
Cost: func(i interface{}) int64 {
switch v := i.(type) {
case string:
return int64(len(v))
case []byte:
return int64(len(v))
default:
return 1
}
},
})
}
func (c *cache) Del(key string) {
c.items.Delete(key)
}
valCache, _ = ristretto.NewCache(&ristretto.Config{
NumCounters: 1e7,
MaxCost: 1 << 32,
BufferItems: 64,
Cost: func(i interface{}) int64 {
switch v := i.(type) {
case string:
return int64(len(v))
case []byte:
return int64(len(v))
default:
return 1
}
},
})
func (c *cache) Has(key string) bool {
_, ok := c.items.Load(key)
return ok
}
func (c *cache) Get(key string) interface{} {
val, _ := c.items.Load(key)
return val
}
func (c *cache) Put(key string, val interface{}) {
c.items.Store(key, val)
}

View file

@ -74,7 +74,7 @@ func (d *document) grant(ctx context.Context, met method) (ok bool, err error) {
// so we can check if the permissions
// allow us to view this document.
tb, err := d.i.e.dbo.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
tb, err := d.i.e.tx.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return false, err
}
@ -161,7 +161,7 @@ func (d *document) allow(ctx context.Context, met method) (ok bool, err error) {
// so we can check if the permissions
// allow us to view this document.
tb, err := d.i.e.dbo.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
tb, err := d.i.e.tx.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return false, err
}

View file

@ -1,3 +1,5 @@
// +build go1.6
// Code generated by codecgen - DO NOT EDIT.
package db
@ -11,44 +13,42 @@ import (
const (
// ----- content types ----
codecSelferCcUTF87751 = 1
codecSelferCcRAW7751 = 255
codecSelferCcUTF84653 = 1
codecSelferCcRAW4653 = 255
// ----- value types used ----
codecSelferValueTypeArray7751 = 10
codecSelferValueTypeMap7751 = 9
codecSelferValueTypeString7751 = 6
codecSelferValueTypeInt7751 = 2
codecSelferValueTypeUint7751 = 3
codecSelferValueTypeFloat7751 = 4
codecSelferBitsize7751 = uint8(32 << (^uint(0) >> 63))
codecSelferValueTypeArray4653 = 10
codecSelferValueTypeMap4653 = 9
codecSelferValueTypeString4653 = 6
codecSelferValueTypeInt4653 = 2
codecSelferValueTypeUint4653 = 3
codecSelferValueTypeFloat4653 = 4
codecSelferValueTypeNil4653 = 1
codecSelferBitsize4653 = uint8(32 << (^uint(0) >> 63))
codecSelferDecContainerLenNil4653 = -2147483648
)
var (
errCodecSelferOnlyMapOrArrayEncodeToStruct7751 = errors.New(`only encoded map or array can be decoded into a struct`)
errCodecSelferOnlyMapOrArrayEncodeToStruct4653 = errors.New(`only encoded map or array can be decoded into a struct`)
)
type codecSelfer7751 struct{}
type codecSelfer4653 struct{}
func codecSelfer4653False() bool { return false }
func init() {
if codec1978.GenVersion != 10 {
if codec1978.GenVersion != 16 {
_, file, _, _ := runtime.Caller(0)
panic("codecgen version mismatch: current: 10, need " + strconv.FormatInt(int64(codec1978.GenVersion), 10) + ". Re-generate file: " + file)
}
if false {
var _ byte = 0 // reference the types, but skip this branch at build/run time
ver := strconv.FormatInt(int64(codec1978.GenVersion), 10)
panic("codecgen version mismatch: current: 16, need " + ver + ". Re-generate file: " + file)
}
}
func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
if false {
} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
z.EncExtension(x, yyxt1)
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
@ -62,7 +62,36 @@ func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
}
_ = yyq2
if yyr2 || yy2arr2 {
r.WriteArrayStart(4)
z.EncWriteArrayStart(4)
z.EncWriteArrayElem()
if yyq2[0] {
r.EncodeString(string(x.Time))
} else {
r.EncodeString("")
}
z.EncWriteArrayElem()
if yyq2[1] {
r.EncodeString(string(x.Status))
} else {
r.EncodeString("")
}
z.EncWriteArrayElem()
if yyq2[2] {
r.EncodeString(string(x.Detail))
} else {
r.EncodeString("")
}
z.EncWriteArrayElem()
if yyq2[3] {
if x.Result == nil {
r.EncodeNil()
} else {
z.F.EncSliceIntfV(x.Result, e)
} // end block: if x.Result slice == nil
} else {
r.EncodeNil()
}
z.EncWriteArrayEnd()
} else {
var yynn2 int
for _, b := range yyq2 {
@ -70,157 +99,84 @@ func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
yynn2++
}
}
r.WriteMapStart(yynn2)
z.EncWriteMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[0] {
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Time))
}
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, "")
}
} else {
if yyq2[0] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"time\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `time`)
r.EncodeString(`time`)
}
r.WriteMapElemValue()
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Time))
z.EncWriteMapElemValue()
r.EncodeString(string(x.Time))
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[1] {
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Status))
}
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, "")
}
} else {
if yyq2[1] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"status\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `status`)
r.EncodeString(`status`)
}
r.WriteMapElemValue()
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Status))
z.EncWriteMapElemValue()
r.EncodeString(string(x.Status))
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[2] {
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Detail))
}
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, "")
}
} else {
if yyq2[2] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"detail\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `detail`)
r.EncodeString(`detail`)
}
r.WriteMapElemValue()
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Detail))
z.EncWriteMapElemValue()
r.EncodeString(string(x.Detail))
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[3] {
if x.Result == nil {
r.EncodeNil()
} else {
if false {
} else {
z.F.EncSliceIntfV(x.Result, e)
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[3] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"result\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `result`)
r.EncodeString(`result`)
}
r.WriteMapElemValue()
z.EncWriteMapElemValue()
if x.Result == nil {
r.EncodeNil()
} else {
if false {
} else {
z.F.EncSliceIntfV(x.Result, e)
} // end block: if x.Result slice == nil
}
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayEnd()
} else {
r.WriteMapEnd()
}
z.EncWriteMapEnd()
}
}
}
func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
if false {
} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
z.DecExtension(x, yyxt1)
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap7751 {
yyl2 := r.ReadMapStart()
if yyct2 == codecSelferValueTypeNil4653 {
*(x) = Response{}
} else if yyct2 == codecSelferValueTypeMap4653 {
yyl2 := z.DecReadMapStart()
if yyl2 == 0 {
r.ReadMapEnd()
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray7751 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
r.ReadArrayEnd()
} else {
z.DecReadMapEnd()
} else if yyct2 == codecSelferValueTypeArray4653 {
yyl2 := z.DecReadArrayStart()
if yyl2 != 0 {
x.codecDecodeSelfFromArray(yyl2, d)
}
z.DecReadArrayEnd()
} else {
panic(errCodecSelferOnlyMapOrArrayEncodeToStruct7751)
}
panic(errCodecSelferOnlyMapOrArrayEncodeToStruct4653)
}
}
func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyhl3 bool = l >= 0
@ -230,50 +186,30 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
break
}
} else {
if r.CheckBreak() {
if z.DecCheckBreak() {
break
}
}
r.ReadMapElemKey()
z.DecReadMapElemKey()
yys3 := z.StringView(r.DecodeStringAsBytes())
r.ReadMapElemValue()
z.DecReadMapElemValue()
switch yys3 {
case "time":
if r.TryDecodeAsNil() {
x.Time = ""
} else {
x.Time = (string)(r.DecodeString())
}
x.Time = (string)(string(r.DecodeStringAsBytes()))
case "status":
if r.TryDecodeAsNil() {
x.Status = ""
} else {
x.Status = (string)(r.DecodeString())
}
x.Status = (string)(string(r.DecodeStringAsBytes()))
case "detail":
if r.TryDecodeAsNil() {
x.Detail = ""
} else {
x.Detail = (string)(r.DecodeString())
}
x.Detail = (string)(string(r.DecodeStringAsBytes()))
case "result":
if r.TryDecodeAsNil() {
x.Result = nil
} else {
if false {
} else {
z.F.DecSliceIntfX(&x.Result, d)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
r.ReadMapEnd()
}
func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj9 int
@ -283,95 +219,71 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if yyhl9 {
yyb9 = yyj9 > l
} else {
yyb9 = r.CheckBreak()
yyb9 = z.DecCheckBreak()
}
if yyb9 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Time = ""
} else {
x.Time = (string)(r.DecodeString())
}
z.DecReadArrayElem()
x.Time = (string)(string(r.DecodeStringAsBytes()))
yyj9++
if yyhl9 {
yyb9 = yyj9 > l
} else {
yyb9 = r.CheckBreak()
yyb9 = z.DecCheckBreak()
}
if yyb9 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Status = ""
} else {
x.Status = (string)(r.DecodeString())
}
z.DecReadArrayElem()
x.Status = (string)(string(r.DecodeStringAsBytes()))
yyj9++
if yyhl9 {
yyb9 = yyj9 > l
} else {
yyb9 = r.CheckBreak()
yyb9 = z.DecCheckBreak()
}
if yyb9 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Detail = ""
} else {
x.Detail = (string)(r.DecodeString())
}
z.DecReadArrayElem()
x.Detail = (string)(string(r.DecodeStringAsBytes()))
yyj9++
if yyhl9 {
yyb9 = yyj9 > l
} else {
yyb9 = r.CheckBreak()
yyb9 = z.DecCheckBreak()
}
if yyb9 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Result = nil
} else {
if false {
} else {
z.DecReadArrayElem()
z.F.DecSliceIntfX(&x.Result, d)
}
}
for {
yyj9++
if yyhl9 {
yyb9 = yyj9 > l
} else {
yyb9 = r.CheckBreak()
yyb9 = z.DecCheckBreak()
}
if yyb9 {
break
}
r.ReadArrayElem()
z.DecReadArrayElem()
z.DecStructFieldNotFound(yyj9-1, "")
}
r.ReadArrayEnd()
}
func (x *Dispatch) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
if false {
} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
z.EncExtension(x, yyxt1)
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
@ -384,7 +296,26 @@ func (x *Dispatch) CodecEncodeSelf(e *codec1978.Encoder) {
}
_ = yyq2
if yyr2 || yy2arr2 {
r.WriteArrayStart(3)
z.EncWriteArrayStart(3)
z.EncWriteArrayElem()
if yyq2[0] {
r.EncodeString(string(x.Query))
} else {
r.EncodeString("")
}
z.EncWriteArrayElem()
if yyq2[1] {
r.EncodeString(string(x.Action))
} else {
r.EncodeString("")
}
z.EncWriteArrayElem()
if yyq2[2] {
z.EncFallback(x.Result)
} else {
r.EncodeNil()
}
z.EncWriteArrayEnd()
} else {
var yynn2 int
for _, b := range yyq2 {
@ -392,132 +323,70 @@ func (x *Dispatch) CodecEncodeSelf(e *codec1978.Encoder) {
yynn2++
}
}
r.WriteMapStart(yynn2)
z.EncWriteMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[0] {
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Query))
}
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, "")
}
} else {
if yyq2[0] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"query\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `query`)
r.EncodeString(`query`)
}
r.WriteMapElemValue()
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Query))
z.EncWriteMapElemValue()
r.EncodeString(string(x.Query))
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[1] {
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Action))
}
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, "")
}
} else {
if yyq2[1] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"action\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `action`)
r.EncodeString(`action`)
}
r.WriteMapElemValue()
if false {
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, string(x.Action))
z.EncWriteMapElemValue()
r.EncodeString(string(x.Action))
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayElem()
if yyq2[2] {
if x.Result == nil {
r.EncodeNil()
} else {
if false {
} else {
z.EncFallback(x.Result)
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
r.WriteMapElemKey()
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"result\"")
} else {
r.EncodeStringEnc(codecSelferCcUTF87751, `result`)
r.EncodeString(`result`)
}
r.WriteMapElemValue()
if x.Result == nil {
r.EncodeNil()
} else {
if false {
} else {
z.EncWriteMapElemValue()
z.EncFallback(x.Result)
}
}
}
}
if yyr2 || yy2arr2 {
r.WriteArrayEnd()
} else {
r.WriteMapEnd()
}
z.EncWriteMapEnd()
}
}
}
func (x *Dispatch) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
if false {
} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
z.DecExtension(x, yyxt1)
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap7751 {
yyl2 := r.ReadMapStart()
if yyct2 == codecSelferValueTypeNil4653 {
*(x) = Dispatch{}
} else if yyct2 == codecSelferValueTypeMap4653 {
yyl2 := z.DecReadMapStart()
if yyl2 == 0 {
r.ReadMapEnd()
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray7751 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
r.ReadArrayEnd()
} else {
z.DecReadMapEnd()
} else if yyct2 == codecSelferValueTypeArray4653 {
yyl2 := z.DecReadArrayStart()
if yyl2 != 0 {
x.codecDecodeSelfFromArray(yyl2, d)
}
z.DecReadArrayEnd()
} else {
panic(errCodecSelferOnlyMapOrArrayEncodeToStruct7751)
}
panic(errCodecSelferOnlyMapOrArrayEncodeToStruct4653)
}
}
func (x *Dispatch) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyhl3 bool = l >= 0
@ -527,44 +396,28 @@ func (x *Dispatch) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
break
}
} else {
if r.CheckBreak() {
if z.DecCheckBreak() {
break
}
}
r.ReadMapElemKey()
z.DecReadMapElemKey()
yys3 := z.StringView(r.DecodeStringAsBytes())
r.ReadMapElemValue()
z.DecReadMapElemValue()
switch yys3 {
case "query":
if r.TryDecodeAsNil() {
x.Query = ""
} else {
x.Query = (string)(r.DecodeString())
}
x.Query = (string)(string(r.DecodeStringAsBytes()))
case "action":
if r.TryDecodeAsNil() {
x.Action = ""
} else {
x.Action = (string)(r.DecodeString())
}
x.Action = (string)(string(r.DecodeStringAsBytes()))
case "result":
if r.TryDecodeAsNil() {
x.Result = nil
} else {
if false {
} else {
z.DecFallback(&x.Result, true)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
r.ReadMapEnd()
}
func (x *Dispatch) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer7751
var h codecSelfer4653
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj8 int
@ -574,65 +427,49 @@ func (x *Dispatch) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
yyb8 = z.DecCheckBreak()
}
if yyb8 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Query = ""
} else {
x.Query = (string)(r.DecodeString())
}
z.DecReadArrayElem()
x.Query = (string)(string(r.DecodeStringAsBytes()))
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
yyb8 = z.DecCheckBreak()
}
if yyb8 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Action = ""
} else {
x.Action = (string)(r.DecodeString())
}
z.DecReadArrayElem()
x.Action = (string)(string(r.DecodeStringAsBytes()))
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
yyb8 = z.DecCheckBreak()
}
if yyb8 {
r.ReadArrayEnd()
z.DecReadArrayEnd()
return
}
r.ReadArrayElem()
if r.TryDecodeAsNil() {
x.Result = nil
} else {
if false {
} else {
z.DecReadArrayElem()
z.DecFallback(&x.Result, true)
}
}
for {
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
yyb8 = z.DecCheckBreak()
}
if yyb8 {
break
}
r.ReadArrayElem()
z.DecReadArrayElem()
z.DecStructFieldNotFound(yyj8-1, "")
}
r.ReadArrayEnd()
}

View file

@ -25,15 +25,12 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/log"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/data"
_ "github.com/abcum/surreal/kvs/rixxdb"
)
var db *kvs.DS
var KV string
var NIL string
@ -61,28 +58,18 @@ func init() {
// Setup sets up the connection with the data layer
func Setup(opts *cnf.Options) (err error) {
log.WithPrefix("db").Infof("Starting database")
KV = cnf.Settings.DB.Base
db, err = kvs.New(opts)
return
}
// Exit shuts down the connection with the data layer
func Exit() (err error) {
log.WithPrefix("db").Infof("Gracefully shutting down database")
func Exit(opts *cnf.Options) (err error) {
sockets.Range(func(key, val interface{}) bool {
id, so := key.(string), val.(*socket)
deregister(so.fibre, id)()
return true
})
return db.Close()
return
}
@ -92,21 +79,14 @@ func Exit() (err error) {
func Sync(rw interface{}) (err error) {
switch v := rw.(type) {
case io.Reader:
return db.Import(v)
return kvs.Import(v)
case io.Writer:
return db.Export(v)
return kvs.Export(v)
default:
return nil
}
}
// Begin begins a new read / write transaction
// with the underlying database, and returns
// the transaction, or any error which occured.
func Begin(rw bool) (txn kvs.TX, err error) {
return db.Begin(context.Background(), rw)
}
// Export saves all database operations to a writer.
// This can be used to save a database snapshot
// to a secondary file or stream.
@ -157,19 +137,11 @@ func Process(fib *fibre.Context, ast *sql.Query, vars map[string]interface{}) (o
vars = make(map[string]interface{})
}
// Ensure that we have a unique id assigned
// to this fibre connection, as we need it
// to detect unique websocket notifications.
if fib.Get(ctxKeyId) == nil {
fib.Set(ctxKeyId, "background")
}
// Get the unique id for this connection
// so that we can assign it to the context
// and detect any websocket notifications.
id := fib.Get(ctxKeyId).(string)
id := fib.Uniq()
// Assign the authentication data to the
// context so that we can log the auth kind

View file

@ -19,6 +19,7 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/util/uuid"
)
@ -37,6 +38,8 @@ func setupDB(workers int) {
cnf.Settings.DB.Base = "surreal"
workerCount = workers
kvs.Setup(cnf.Settings)
Setup(cnf.Settings)
}

View file

@ -33,7 +33,7 @@ func (e *executor) executeDefineNamespace(ctx context.Context, ast *sql.DefineNa
// Save the namespace definition
nkey := &keys.NS{KV: KV, NS: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, nkey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, nkey.Encode(), ast.Encode())
return
@ -45,11 +45,11 @@ func (e *executor) executeDefineDatabase(ctx context.Context, ast *sql.DefineDat
return nil, err
}
e.dbo.AddNS(ctx, e.ns)
e.tx.AddNS(ctx, e.ns)
// Save the database definition
dkey := &keys.DB{KV: KV, NS: e.ns, DB: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, dkey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, dkey.Encode(), ast.Encode())
return
@ -73,11 +73,11 @@ func (e *executor) executeDefineLogin(ctx context.Context, ast *sql.DefineLoginS
return nil, err
}
e.dbo.AddNS(ctx, e.ns)
e.tx.AddNS(ctx, e.ns)
// Save the login definition
ukey := &keys.NU{KV: KV, NS: e.ns, US: ast.User.VA}
_, err = e.dbo.Put(ctx, 0, ukey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, ukey.Encode(), ast.Encode())
case sql.DATABASE:
@ -85,11 +85,11 @@ func (e *executor) executeDefineLogin(ctx context.Context, ast *sql.DefineLoginS
return nil, err
}
e.dbo.AddDB(ctx, e.ns, e.db)
e.tx.AddDB(ctx, e.ns, e.db)
// Save the login definition
ukey := &keys.DU{KV: KV, NS: e.ns, DB: e.db, US: ast.User.VA}
_, err = e.dbo.Put(ctx, 0, ukey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, ukey.Encode(), ast.Encode())
}
@ -106,11 +106,11 @@ func (e *executor) executeDefineToken(ctx context.Context, ast *sql.DefineTokenS
return nil, err
}
e.dbo.AddNS(ctx, e.ns)
e.tx.AddNS(ctx, e.ns)
// Save the token definition
tkey := &keys.NT{KV: KV, NS: e.ns, TK: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, tkey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, tkey.Encode(), ast.Encode())
case sql.DATABASE:
@ -118,11 +118,11 @@ func (e *executor) executeDefineToken(ctx context.Context, ast *sql.DefineTokenS
return nil, err
}
e.dbo.AddDB(ctx, e.ns, e.db)
e.tx.AddDB(ctx, e.ns, e.db)
// Save the token definition
tkey := &keys.DT{KV: KV, NS: e.ns, DB: e.db, TK: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, tkey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, tkey.Encode(), ast.Encode())
case sql.SCOPE:
@ -130,11 +130,11 @@ func (e *executor) executeDefineToken(ctx context.Context, ast *sql.DefineTokenS
return nil, err
}
e.dbo.AddDB(ctx, e.ns, e.db)
e.tx.AddDB(ctx, e.ns, e.db)
// Save the token definition
tkey := &keys.ST{KV: KV, NS: e.ns, DB: e.db, SC: ast.What.VA, TK: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, tkey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, tkey.Encode(), ast.Encode())
}
@ -150,11 +150,11 @@ func (e *executor) executeDefineScope(ctx context.Context, ast *sql.DefineScopeS
ast.Code = rand.New(128)
e.dbo.AddDB(ctx, e.ns, e.db)
e.tx.AddDB(ctx, e.ns, e.db)
// Remove the scope definition
skey := &keys.SC{KV: KV, NS: e.ns, DB: e.db, SC: ast.Name.VA}
_, err = e.dbo.Put(ctx, 0, skey.Encode(), ast.Encode())
_, err = e.tx.Put(ctx, 0, skey.Encode(), ast.Encode())
return
@ -168,11 +168,11 @@ func (e *executor) executeDefineEvent(ctx context.Context, ast *sql.DefineEventS
for _, TB := range ast.What {
e.dbo.AddTB(ctx, e.ns, e.db, TB.TB)
e.tx.AddTB(ctx, e.ns, e.db, TB.TB)
// Remove the event definition
ekey := &keys.EV{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, EV: ast.Name.VA}
if _, err = e.dbo.Put(ctx, 0, ekey.Encode(), ast.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, ekey.Encode(), ast.Encode()); err != nil {
return nil, err
}
@ -190,11 +190,11 @@ func (e *executor) executeDefineField(ctx context.Context, ast *sql.DefineFieldS
for _, TB := range ast.What {
e.dbo.AddTB(ctx, e.ns, e.db, TB.TB)
e.tx.AddTB(ctx, e.ns, e.db, TB.TB)
// Save the field definition
fkey := &keys.FD{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, FD: ast.Name.VA}
if _, err = e.dbo.Put(ctx, 0, fkey.Encode(), ast.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, fkey.Encode(), ast.Encode()); err != nil {
return nil, err
}
@ -212,17 +212,17 @@ func (e *executor) executeDefineIndex(ctx context.Context, ast *sql.DefineIndexS
for _, TB := range ast.What {
e.dbo.AddTB(ctx, e.ns, e.db, TB.TB)
e.tx.AddTB(ctx, e.ns, e.db, TB.TB)
// Save the index definition
ikey := &keys.IX{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, IX: ast.Name.VA}
if _, err = e.dbo.Put(ctx, 0, ikey.Encode(), ast.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, ikey.Encode(), ast.Encode()); err != nil {
return nil, err
}
// Remove the index resource data
dkey := &keys.Index{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, IX: ast.Name.VA, FD: keys.Ignore}
if _, err = e.dbo.ClrP(ctx, dkey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, dkey.Encode(), 0); err != nil {
return nil, err
}
@ -245,7 +245,7 @@ func (e *executor) executeDefineTable(ctx context.Context, ast *sql.DefineTableS
return nil, err
}
e.dbo.AddDB(ctx, e.ns, e.db)
e.tx.AddDB(ctx, e.ns, e.db)
for _, TB := range ast.What {
@ -253,7 +253,7 @@ func (e *executor) executeDefineTable(ctx context.Context, ast *sql.DefineTableS
// Save the table definition
tkey := &keys.TB{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB}
if _, err = e.dbo.Put(ctx, 0, tkey.Encode(), ast.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, tkey.Encode(), ast.Encode()); err != nil {
return nil, err
}
@ -261,7 +261,7 @@ func (e *executor) executeDefineTable(ctx context.Context, ast *sql.DefineTableS
// Remove the table resource data
dkey := &keys.Table{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB}
if _, err = e.dbo.ClrP(ctx, dkey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, dkey.Encode(), 0); err != nil {
return nil, err
}
@ -269,7 +269,7 @@ func (e *executor) executeDefineTable(ctx context.Context, ast *sql.DefineTableS
// Save the foreign table definition
tkey := &keys.FT{KV: KV, NS: e.ns, DB: e.db, TB: FT.TB, FT: TB.TB}
if _, err = e.dbo.Put(ctx, 0, tkey.Encode(), ast.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, tkey.Encode(), ast.Encode()); err != nil {
return nil, err
}

View file

@ -111,8 +111,13 @@ func (d *document) init(ctx context.Context) (err error) {
if d.key == nil && d.val != nil {
d.enc = d.val.Key()
if val, ok := keyCache.Get(d.val.Key()); ok {
d.key = val.(*keys.Thing)
} else {
d.key = &keys.Thing{}
d.key.Decode(d.enc)
keyCache.Set(d.val.Key(), d.key, 0)
}
}
return
@ -150,7 +155,7 @@ func (d *document) setup(ctx context.Context) (err error) {
if d.key != nil && d.val == nil {
d.enc = d.key.Encode()
d.val, err = d.i.e.dbo.Get(ctx, d.i.versn, d.enc)
d.val, err = d.i.e.tx.Get(ctx, d.i.versn, d.enc)
if err != nil {
return
}
@ -163,9 +168,8 @@ func (d *document) setup(ctx context.Context) (err error) {
// maniuplate the virtual document.
if d.doc != nil {
enc := d.doc.Encode()
d.initial = data.New().Decode(enc)
d.current = data.New().Decode(enc)
d.initial = d.doc
d.current = d.doc
}
// The requested record has been loaded
@ -186,8 +190,14 @@ func (d *document) setup(ctx context.Context) (err error) {
// processing any record changes.
if d.doc == nil && d.val != nil && d.val.Exi() == true {
if val, ok := valCache.Get(d.val.Val()); ok {
d.initial = val.(*data.Doc)
d.current = d.initial
} else {
d.initial = data.New().Decode(d.val.Val())
d.current = data.New().Decode(d.val.Val())
d.current = d.initial
valCache.Set(d.val.Val(), d.current, 0)
}
}
// Finally if we are dealing with a record
@ -219,7 +229,7 @@ func (d *document) shouldDrop(ctx context.Context) (bool, error) {
// that the table should drop
// writes, and if so, then return.
tb, err := d.i.e.dbo.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
tb, err := d.i.e.tx.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return false, err
}
@ -234,7 +244,7 @@ func (d *document) shouldVersn(ctx context.Context) (bool, error) {
// that the table should keep
// all document versions.
tb, err := d.i.e.dbo.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
tb, err := d.i.e.tx.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return false, err
}
@ -267,9 +277,9 @@ func (d *document) storeThing(ctx context.Context) (err error) {
if ok, err := d.shouldVersn(ctx); err != nil {
return err
} else if ok == true {
_, err = d.i.e.dbo.Put(ctx, d.i.e.time, d.enc, d.current.Encode())
_, err = d.i.e.tx.Put(ctx, d.i.e.time.UnixNano(), d.enc, d.current.Encode())
} else if ok == false {
_, err = d.i.e.dbo.Put(ctx, 0, d.enc, d.current.Encode())
_, err = d.i.e.tx.Put(ctx, 0, d.enc, d.current.Encode())
}
return
@ -293,9 +303,9 @@ func (d *document) purgeThing(ctx context.Context) (err error) {
if ok, err := d.shouldVersn(ctx); err != nil {
return err
} else if ok == true {
_, err = d.i.e.dbo.Put(ctx, d.i.e.time, d.enc, nil)
_, err = d.i.e.tx.Put(ctx, d.i.e.time.UnixNano(), d.enc, nil)
} else if ok == false {
_, err = d.i.e.dbo.Clr(ctx, d.enc)
_, err = d.i.e.tx.Clr(ctx, d.enc)
}
return
@ -327,7 +337,7 @@ func (d *document) storeIndex(ctx context.Context) (err error) {
// for this table, loop through
// them, and compute the changes.
ixs, err := d.i.e.dbo.AllIX(ctx, d.key.NS, d.key.DB, d.key.TB)
ixs, err := d.i.e.tx.AllIX(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}
@ -345,12 +355,12 @@ func (d *document) storeIndex(ctx context.Context) (err error) {
for _, f := range del {
enfd := data.Consume(f).Encode()
didx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd}
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
d.i.e.tx.DelC(ctx, d.i.e.time.UnixNano(), didx.Encode(), d.id.Bytes())
}
for _, f := range add {
enfd := data.Consume(f).Encode()
aidx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd}
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
if _, err = d.i.e.tx.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: f}
}
}
@ -360,12 +370,12 @@ func (d *document) storeIndex(ctx context.Context) (err error) {
for _, f := range del {
enfd := data.Consume(f).Encode()
didx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd, ID: d.key.ID}
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
d.i.e.tx.DelC(ctx, d.i.e.time.UnixNano(), didx.Encode(), d.id.Bytes())
}
for _, f := range add {
enfd := data.Consume(f).Encode()
aidx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd, ID: d.key.ID}
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
if _, err = d.i.e.tx.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: f}
}
}
@ -402,7 +412,7 @@ func (d *document) purgeIndex(ctx context.Context) (err error) {
// for this table, loop through
// them, and compute the changes.
ixs, err := d.i.e.dbo.AllIX(ctx, d.key.NS, d.key.DB, d.key.TB)
ixs, err := d.i.e.tx.AllIX(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}
@ -414,14 +424,14 @@ func (d *document) purgeIndex(ctx context.Context) (err error) {
if ix.Uniq == true {
for _, v := range del {
key := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v}
d.i.e.dbo.DelC(ctx, 0, key.Encode(), d.id.Bytes())
d.i.e.tx.DelC(ctx, 0, key.Encode(), d.id.Bytes())
}
}
if ix.Uniq == false {
for _, v := range del {
key := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v, ID: d.key.ID}
d.i.e.dbo.DelC(ctx, 0, key.Encode(), d.id.Bytes())
d.i.e.tx.DelC(ctx, 0, key.Encode(), d.id.Bytes())
}
}

View file

@ -47,7 +47,7 @@ func (d *document) event(ctx context.Context, met method) (err error) {
// for this table, loop through
// them, and compute the events.
evs, err := d.i.e.dbo.AllEV(ctx, d.key.NS, d.key.DB, d.key.TB)
evs, err := d.i.e.tx.AllEV(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}

View file

@ -15,6 +15,7 @@
package db
import (
"sync"
"time"
"context"
@ -23,20 +24,22 @@ import (
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/log"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
)
type executor struct {
id string
ns string
db string
dbo *mem.Cache
time int64
tx *txn.TX
err error
buf []*Response
time time.Time
lock *mutex
opts *options
data sync.Map
send chan *Response
cache *cache
}
func newExecutor(id, ns, db string) (e *executor) {
@ -47,14 +50,14 @@ func newExecutor(id, ns, db string) (e *executor) {
e.ns = ns
e.db = db
e.dbo = mem.New()
e.err = nil
e.data = sync.Map{}
e.opts = newOptions()
e.send = make(chan *Response)
e.cache = new(cache)
return
}
@ -78,8 +81,8 @@ func (e *executor) execute(ctx context.Context, ast *sql.Query) {
// query set, then cancel the transaction.
defer func() {
if e.dbo.TX != nil {
e.dbo.Cancel()
if e.tx != nil {
e.tx.Cancel()
clear(e.id)
}
}()
@ -115,18 +118,15 @@ func (e *executor) execute(ctx context.Context, ast *sql.Query) {
func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
var err error
var now time.Time
var rsp *Response
var buf []*Response
var res []interface{}
// If we are not inside a global transaction
// then reset the error to nil so that the
// next statement is not ignored.
if e.dbo.TX == nil {
err, now = nil, time.Now()
if e.tx == nil {
e.err = nil
}
// Check to see if the current statement is
@ -135,20 +135,22 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
switch stm.(type) {
case *sql.BeginStatement:
e.lock = new(mutex)
err = e.begin(ctx, true)
e.err = e.begin(ctx, true)
if e.err != nil {
clear(e.id)
}
return
case *sql.CancelStatement:
err, buf = e.cancel(buf, err, e.send)
if err != nil {
e.err = e.cancel(e.send)
if e.err != nil {
clear(e.id)
} else {
clear(e.id)
}
return
case *sql.CommitStatement:
err, buf = e.commit(buf, err, e.send)
if err != nil {
e.err = e.commit(e.send)
if e.err != nil {
clear(e.id)
} else {
flush(e.id)
@ -160,16 +162,18 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
// a global transaction, then ignore all
// subsequent statements in the transaction.
if err == nil {
res, err = e.operate(ctx, stm)
if e.err == nil {
res, e.err = e.operate(ctx, stm)
} else {
res, err = []interface{}{}, errQueryNotExecuted
res, e.err = []interface{}{}, errQueryNotExecuted
}
// Generate the response
rsp = &Response{
Time: time.Since(now).String(),
Status: status(err),
Detail: detail(err),
Time: time.Since(e.time).String(),
Status: status(e.err),
Detail: detail(e.err),
Result: append([]interface{}{}, res...),
}
@ -177,7 +181,7 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
// query duration time, and mark it as
// an error if the query failed.
switch err.(type) {
switch e.err.(type) {
default:
if log.IsDebug() {
log.WithPrefix(logKeySql).WithFields(map[string]interface{}{
@ -186,7 +190,7 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
logKeyDB: e.db,
logKeyKind: ctx.Value(ctxKeyKind),
logKeyVars: ctx.Value(ctxKeyVars),
logKeyTime: time.Since(now).String(),
logKeyTime: time.Since(e.time).String(),
}).Debugln(stm)
}
case error:
@ -197,8 +201,8 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
logKeyDB: e.db,
logKeyKind: ctx.Value(ctxKeyKind),
logKeyVars: ctx.Value(ctxKeyVars),
logKeyTime: time.Since(now).String(),
logKeyError: detail(err),
logKeyTime: time.Since(e.time).String(),
logKeyError: detail(e.err),
}).Errorln(stm)
}
}
@ -207,7 +211,7 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
// then we can output the statement response
// immediately to the channel.
if e.dbo.TX == nil {
if e.tx == nil {
e.send <- rsp
}
@ -215,12 +219,16 @@ func (e *executor) conduct(ctx context.Context, stm sql.Statement) {
// must buffer the responses for output at
// the end of the transaction.
if e.dbo.TX != nil {
if e.tx != nil {
switch stm.(type) {
case *sql.ReturnStatement:
buf = groupd(buf, rsp)
for i := len(e.buf) - 1; i >= 0; i-- {
e.buf[len(e.buf)-1] = nil
e.buf = e.buf[:len(e.buf)-1]
}
e.buf = append(e.buf, rsp)
default:
buf = append(buf, rsp)
e.buf = append(e.buf, rsp)
}
}
@ -236,15 +244,13 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
// then grab a new transaction, ensuring that
// it is closed at the end.
if e.dbo.TX == nil {
loc = true
if e.tx == nil {
switch stm := stm.(type) {
case sql.WriteableStatement:
trw = stm.Writeable()
loc, trw = true, stm.Writeable()
default:
trw = false
loc, trw = true, false
}
err = e.begin(ctx, trw)
@ -252,13 +258,10 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
return
}
defer e.dbo.Cancel()
// Let's create a new mutex for just this
// local transaction, so we can track any
// recursive queries and race errors.
e.lock = new(mutex)
defer func() {
e.tx.Cancel()
e.tx = nil
}()
}
@ -278,12 +281,6 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
}
}
// Specify a new time for the current executor
// iteration, so that all subqueries and async
// events are saved with the same version time.
e.time = time.Now().UnixNano()
// Execute the defined statement, receiving the
// result set, and any errors which occured
// while processing the query.
@ -385,8 +382,7 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
case <-ctx.Done():
e.dbo.Cancel()
e.dbo.Reset()
e.tx.Cancel()
clear(e.id)
default:
@ -395,20 +391,14 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
// current statement, then commit or cancel
// depending on the result error.
if loc && e.dbo.Closed() == false {
// As this is a local transaction then
// make sure we reset the transaction
// context.
defer e.dbo.Reset()
if loc {
// If there was an error with the query
// then clear the queued changes and
// return immediately.
if err != nil {
e.dbo.Cancel()
e.tx.Cancel()
clear(e.id)
return
}
@ -418,13 +408,13 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
// Cancel or Commit, returning any errors.
if !trw {
if err = e.dbo.Cancel(); err != nil {
if err = e.tx.Cancel(); err != nil {
clear(e.id)
} else {
clear(e.id)
}
} else {
if err = e.dbo.Commit(); err != nil {
if err = e.tx.Commit(); err != nil {
clear(e.id)
} else {
flush(e.id)
@ -440,55 +430,51 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
}
func (e *executor) begin(ctx context.Context, rw bool) (err error) {
if e.dbo.TX == nil {
e.dbo = mem.New()
e.dbo.TX, err = db.Begin(ctx, rw)
}
e.tx, err = txn.New(ctx, rw)
e.time = time.Now()
e.lock = new(mutex)
return
}
func (e *executor) cancel(buf []*Response, err error, chn chan<- *Response) (error, []*Response) {
func (e *executor) cancel(chn chan<- *Response) (err error) {
defer e.dbo.Reset()
defer func() {
e.tx.Cancel()
e.tx = nil
e.buf = nil
e.err = nil
}()
if e.dbo.TX == nil {
return nil, buf
}
err = e.dbo.Cancel()
for _, v := range buf {
for _, v := range e.buf {
v.Time = time.Since(e.time).String()
v.Status = "ERR"
v.Result = []interface{}{}
v.Detail = "Transaction cancelled"
chn <- v
}
for i := len(buf) - 1; i >= 0; i-- {
buf[len(buf)-1] = nil
buf = buf[:len(buf)-1]
}
return err, buf
return
}
func (e *executor) commit(buf []*Response, err error, chn chan<- *Response) (error, []*Response) {
func (e *executor) commit(chn chan<- *Response) (err error) {
defer e.dbo.Reset()
defer func() {
e.tx.Cancel()
e.tx = nil
e.buf = nil
e.err = nil
}()
if e.dbo.TX == nil {
return nil, buf
}
if err != nil {
err = e.dbo.Cancel()
if e.err != nil {
err = e.tx.Cancel()
} else {
err = e.dbo.Commit()
err = e.tx.Commit()
}
for _, v := range buf {
for _, v := range e.buf {
if err != nil {
v.Time = time.Since(e.time).String()
v.Status = "ERR"
v.Result = []interface{}{}
v.Detail = "Transaction failed: " + err.Error()
@ -496,12 +482,7 @@ func (e *executor) commit(buf []*Response, err error, chn chan<- *Response) (err
chn <- v
}
for i := len(buf) - 1; i >= 0; i-- {
buf[len(buf)-1] = nil
buf = buf[:len(buf)-1]
}
return err, buf
return
}
@ -536,11 +517,3 @@ func detail(e error) (s string) {
return err.Error()
}
}
func groupd(buf []*Response, rsp *Response) []*Response {
for i := len(buf) - 1; i >= 0; i-- {
buf[len(buf)-1] = nil
buf = buf[:len(buf)-1]
}
return append(buf, rsp)
}

View file

@ -56,7 +56,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Tokens
// ------------------------------
dts, err := exe.dbo.AllDT(ctx, NS, DB)
dts, err := exe.tx.AllDT(ctx, NS, DB)
if err != nil {
return err
}
@ -73,7 +73,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Logins
// ------------------------------
dus, err := exe.dbo.AllDU(ctx, NS, DB)
dus, err := exe.tx.AllDU(ctx, NS, DB)
if err != nil {
return err
}
@ -90,7 +90,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Scopes
// ------------------------------
scs, err := exe.dbo.AllSC(ctx, NS, DB)
scs, err := exe.tx.AllSC(ctx, NS, DB)
if err != nil {
return err
}
@ -109,7 +109,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Tokens
// ------------------------------
sct, err := exe.dbo.AllST(ctx, NS, DB, v.Name.VA)
sct, err := exe.tx.AllST(ctx, NS, DB, v.Name.VA)
if err != nil {
return err
}
@ -130,7 +130,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Tables
// ------------------------------
tbs, err := exe.dbo.AllTB(ctx, NS, DB)
tbs, err := exe.tx.AllTB(ctx, NS, DB)
if err != nil {
return err
}
@ -161,7 +161,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Events
// ------------------------------
evs, err := exe.dbo.AllEV(ctx, NS, DB, TB.Name.VA)
evs, err := exe.tx.AllEV(ctx, NS, DB, TB.Name.VA)
if err != nil {
return err
}
@ -177,7 +177,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Fields
// ------------------------------
fds, err := exe.dbo.AllFD(ctx, NS, DB, TB.Name.VA)
fds, err := exe.tx.AllFD(ctx, NS, DB, TB.Name.VA)
if err != nil {
return err
}
@ -193,7 +193,7 @@ func export(c *fibre.Context, NS, DB string) error {
// Indexes
// ------------------------------
ixs, err := exe.dbo.AllIX(ctx, NS, DB, TB.Name.VA)
ixs, err := exe.tx.AllIX(ctx, NS, DB, TB.Name.VA)
if err != nil {
return err
}
@ -236,9 +236,9 @@ TB:
var vls []kvs.KV
if TB.Vers {
vls, err = exe.dbo.AllR(ctx, min, max, 10000)
vls, err = exe.tx.AllR(ctx, min, max, 10000)
} else {
vls, err = exe.dbo.GetR(ctx, math.MaxInt64, min, max, 10000)
vls, err = exe.tx.GetR(ctx, math.MaxInt64, min, max, 10000)
}
if err != nil {

View file

@ -16,7 +16,6 @@ package db
import (
"context"
"fmt"
"math"
"reflect"
"regexp"
@ -28,7 +27,6 @@ import (
"golang.org/x/text/search"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/log"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/data"
"github.com/abcum/surreal/util/deep"
@ -344,10 +342,8 @@ func (e *executor) fetchThing(ctx context.Context, val *sql.Thing, doc *data.Doc
return nil, err
}
key := fmt.Sprintf("%d %s", ver, val)
if e.cache.Has(key) {
return e.cache.Get(key), nil
if val, ok := e.data.Load(val.String()); ok {
return val, nil
}
stm := &sql.SelectStatement{
@ -356,21 +352,13 @@ func (e *executor) fetchThing(ctx context.Context, val *sql.Thing, doc *data.Doc
Version: sql.Expr(ver),
}
if log.IsTrace() {
log.WithPrefix(logKeyExe).WithFields(map[string]interface{}{
logKeyId: e.id,
logKeyNS: e.ns,
logKeyDB: e.db,
}).Traceln(stm)
}
res, err := e.executeSelect(ctx, stm)
if err != nil {
return nil, err
}
if len(res) > 0 {
e.cache.Put(key, res[0])
e.data.Store(val.String(), res[0])
return res[0], nil
}
@ -378,47 +366,6 @@ func (e *executor) fetchThing(ctx context.Context, val *sql.Thing, doc *data.Doc
}
func (e *executor) fetchArray(ctx context.Context, val []interface{}, doc *data.Doc) (interface{}, error) {
ver, err := e.fetchVersion(ctx, ctx.Value(ctxKeyVersion))
if err != nil {
return nil, err
}
key := fmt.Sprintf("%d %s", ver, val)
if e.cache.Has(key) {
return e.cache.Get(key), nil
}
stm := &sql.SelectStatement{
Expr: []*sql.Field{{Expr: &sql.All{}}},
What: []sql.Expr{val},
Version: sql.Expr(ver),
}
if log.IsTrace() {
log.WithPrefix(logKeyExe).WithFields(map[string]interface{}{
logKeyId: e.id,
logKeyNS: e.ns,
logKeyDB: e.db,
}).Traceln(stm)
}
res, err := e.executeSelect(ctx, stm)
if err != nil {
return nil, err
}
if len(res) > 0 {
e.cache.Put(key, res)
return res, nil
}
return nil, nil
}
func (e *executor) fetchPerms(ctx context.Context, val sql.Expr, tb *sql.Ident) error {
// If the table does exist we reset the

View file

@ -14,5 +14,5 @@
package db
//go:generate go get -u github.com/ugorji/go/codec/codecgen@v0.0.0-20181204163529-d75b2dcb6bc8
//go:generate go get -u github.com/ugorji/go/codec/codecgen
//go:generate codecgen -o db.gen.go db.go

View file

@ -47,7 +47,7 @@ func (e *executor) executeInfoKV(ctx context.Context, ast *sql.InfoStatement) (o
return nil, err
}
ns, err := e.dbo.AllNS(ctx)
ns, err := e.tx.AllNS(ctx)
if err != nil {
return nil, err
}
@ -71,17 +71,17 @@ func (e *executor) executeInfoNS(ctx context.Context, ast *sql.InfoStatement) (o
return nil, err
}
db, err := e.dbo.AllDB(ctx, e.ns)
db, err := e.tx.AllDB(ctx, e.ns)
if err != nil {
return nil, err
}
nt, err := e.dbo.AllNT(ctx, e.ns)
nt, err := e.tx.AllNT(ctx, e.ns)
if err != nil {
return nil, err
}
nu, err := e.dbo.AllNU(ctx, e.ns)
nu, err := e.tx.AllNU(ctx, e.ns)
if err != nil {
return nil, err
}
@ -117,22 +117,22 @@ func (e *executor) executeInfoDB(ctx context.Context, ast *sql.InfoStatement) (o
return nil, err
}
tb, err := e.dbo.AllTB(ctx, e.ns, e.db)
tb, err := e.tx.AllTB(ctx, e.ns, e.db)
if err != nil {
return nil, err
}
dt, err := e.dbo.AllDT(ctx, e.ns, e.db)
dt, err := e.tx.AllDT(ctx, e.ns, e.db)
if err != nil {
return nil, err
}
du, err := e.dbo.AllDU(ctx, e.ns, e.db)
du, err := e.tx.AllDU(ctx, e.ns, e.db)
if err != nil {
return nil, err
}
sc, err := e.dbo.AllSC(ctx, e.ns, e.db)
sc, err := e.tx.AllSC(ctx, e.ns, e.db)
if err != nil {
return nil, err
}
@ -174,7 +174,7 @@ func (e *executor) executeInfoSC(ctx context.Context, ast *sql.InfoStatement) (o
return nil, err
}
st, err := e.dbo.AllST(ctx, e.ns, e.db, ast.What.VA)
st, err := e.tx.AllST(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
@ -198,22 +198,27 @@ func (e *executor) executeInfoTB(ctx context.Context, ast *sql.InfoStatement) (o
return nil, err
}
ev, err := e.dbo.AllEV(ctx, e.ns, e.db, ast.What.VA)
ev, err := e.tx.AllEV(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
fd, err := e.dbo.AllFD(ctx, e.ns, e.db, ast.What.VA)
fd, err := e.tx.AllFD(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
ix, err := e.dbo.AllIX(ctx, e.ns, e.db, ast.What.VA)
ix, err := e.tx.AllIX(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
ft, err := e.dbo.AllFT(ctx, e.ns, e.db, ast.What.VA)
ft, err := e.tx.AllFT(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
lv, err := e.tx.AllLV(ctx, e.ns, e.db, ast.What.VA)
if err != nil {
return nil, err
}
@ -240,10 +245,16 @@ func (e *executor) executeInfoTB(ctx context.Context, ast *sql.InfoStatement) (o
table[v.Name.VA] = v.String()
}
lives := make(map[string]interface{})
for _, v := range lv {
lives[v.ID] = v.String()
}
res.Set(event, "event")
res.Set(field, "field")
res.Set(index, "index")
res.Set(table, "table")
res.Set(lives, "lives")
return []interface{}{res.Data()}, nil

View file

@ -375,7 +375,7 @@ func (i *iterator) processPerms(ctx context.Context, nsv, dbv, tbv string) {
// we need to fetch the table to ensure
// that the table is not a view table.
tb, i.err = i.e.dbo.AddTB(ctx, nsv, dbv, tbv)
tb, i.err = i.e.tx.AddTB(ctx, nsv, dbv, tbv)
if i.err != nil {
close(i.stop)
return
@ -425,7 +425,7 @@ func (i *iterator) processPerms(ctx context.Context, nsv, dbv, tbv string) {
// otherwise, the scoped authentication
// request can not do anything.
_, i.err = i.e.dbo.GetNS(ctx, nsv)
_, i.err = i.e.tx.GetNS(ctx, nsv)
if i.err != nil {
close(i.stop)
return
@ -435,7 +435,7 @@ func (i *iterator) processPerms(ctx context.Context, nsv, dbv, tbv string) {
// otherwise, the scoped authentication
// request can not do anything.
_, i.err = i.e.dbo.GetDB(ctx, nsv, dbv)
_, i.err = i.e.tx.GetDB(ctx, nsv, dbv)
if i.err != nil {
close(i.stop)
return
@ -445,7 +445,7 @@ func (i *iterator) processPerms(ctx context.Context, nsv, dbv, tbv string) {
// otherwise, the scoped authentication
// request can not do anything.
tb, i.err = i.e.dbo.GetTB(ctx, nsv, dbv, tbv)
tb, i.err = i.e.tx.GetTB(ctx, nsv, dbv, tbv)
if i.err != nil {
close(i.stop)
return
@ -549,7 +549,7 @@ func (i *iterator) processTable(ctx context.Context, key *keys.Table) {
return
}
vals, i.err = i.e.dbo.GetR(ctx, i.versn, min, max, 10000)
vals, i.err = i.e.tx.GetR(ctx, i.versn, min, max, 10000)
if i.err != nil {
close(i.stop)
return

View file

@ -42,7 +42,7 @@ func (d *document) lives(ctx context.Context, when method) (err error) {
// specified for this table, and
// update values which have changed.
lvs, err := d.i.e.dbo.AllLV(ctx, d.key.NS, d.key.DB, d.key.TB)
lvs, err := d.i.e.tx.AllLV(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}

View file

@ -35,6 +35,10 @@ var main = map[string]struct{}{
func (d *document) merge(ctx context.Context, met method, data sql.Expr) (err error) {
if err = d.defDoc(ctx, met); err != nil {
return
}
if err = d.defFld(ctx, met); err != nil {
return
}
@ -80,6 +84,14 @@ func (d *document) merge(ctx context.Context, met method, data sql.Expr) (err er
}
func (d *document) defDoc(ctx context.Context, met method) (err error) {
d.current = d.current.Copy()
return
}
func (d *document) defFld(ctx context.Context, met method) (err error) {
switch d.i.vir {
@ -100,7 +112,7 @@ func (d *document) defFld(ctx context.Context, met method) (err error) {
func (d *document) delFld(ctx context.Context, met method) (err error) {
tb, err := d.i.e.dbo.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
tb, err := d.i.e.tx.GetTB(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}
@ -111,7 +123,7 @@ func (d *document) delFld(ctx context.Context, met method) (err error) {
// Get the defined fields
fds, err := d.i.e.dbo.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
fds, err := d.i.e.tx.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}
@ -269,7 +281,7 @@ func (d *document) mrgSet(ctx context.Context, met method, expr *sql.DataExpress
func (d *document) mrgFld(ctx context.Context, met method) (err error) {
fds, err := d.i.e.dbo.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
fds, err := d.i.e.tx.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}

View file

@ -45,7 +45,7 @@ func (d *document) perms(ctx context.Context, doc *data.Doc) (err error) {
// check if the permissions allow us
// to view each field.
fds, err := d.i.e.dbo.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
fds, err := d.i.e.tx.AllFD(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}

View file

@ -28,15 +28,15 @@ func (e *executor) executeRemoveNamespace(ctx context.Context, ast *sql.RemoveNa
return nil, err
}
e.dbo.DelNS(ast.Name.VA)
e.tx.DelNS(ast.Name.VA)
// Remove the namespace definition
nkey := &keys.NS{KV: KV, NS: ast.Name.VA}
_, err = e.dbo.Clr(ctx, nkey.Encode())
_, err = e.tx.Clr(ctx, nkey.Encode())
// Remove the namespace resource data
akey := &keys.Namespace{KV: KV, NS: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, akey.Encode(), 0)
_, err = e.tx.ClrP(ctx, akey.Encode(), 0)
return
@ -48,15 +48,15 @@ func (e *executor) executeRemoveDatabase(ctx context.Context, ast *sql.RemoveDat
return nil, err
}
e.dbo.DelDB(e.ns, ast.Name.VA)
e.tx.DelDB(e.ns, ast.Name.VA)
// Remove the database definition
dkey := &keys.DB{KV: KV, NS: e.ns, DB: ast.Name.VA}
_, err = e.dbo.Clr(ctx, dkey.Encode())
_, err = e.tx.Clr(ctx, dkey.Encode())
// Remove the database resource data
akey := &keys.Database{KV: KV, NS: e.ns, DB: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, akey.Encode(), 0)
_, err = e.tx.ClrP(ctx, akey.Encode(), 0)
return
@ -73,7 +73,7 @@ func (e *executor) executeRemoveLogin(ctx context.Context, ast *sql.RemoveLoginS
// Remove the login definition
ukey := &keys.NU{KV: KV, NS: e.ns, US: ast.User.VA}
_, err = e.dbo.ClrP(ctx, ukey.Encode(), 0)
_, err = e.tx.ClrP(ctx, ukey.Encode(), 0)
case sql.DATABASE:
@ -83,7 +83,7 @@ func (e *executor) executeRemoveLogin(ctx context.Context, ast *sql.RemoveLoginS
// Remove the login definition
ukey := &keys.DU{KV: KV, NS: e.ns, DB: e.db, US: ast.User.VA}
_, err = e.dbo.ClrP(ctx, ukey.Encode(), 0)
_, err = e.tx.ClrP(ctx, ukey.Encode(), 0)
}
@ -106,7 +106,7 @@ func (e *executor) executeRemoveToken(ctx context.Context, ast *sql.RemoveTokenS
// Remove the token definition
tkey := &keys.NT{KV: KV, NS: e.ns, TK: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, tkey.Encode(), 0)
_, err = e.tx.ClrP(ctx, tkey.Encode(), 0)
case sql.DATABASE:
@ -116,7 +116,7 @@ func (e *executor) executeRemoveToken(ctx context.Context, ast *sql.RemoveTokenS
// Remove the token definition
tkey := &keys.DT{KV: KV, NS: e.ns, DB: e.db, TK: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, tkey.Encode(), 0)
_, err = e.tx.ClrP(ctx, tkey.Encode(), 0)
case sql.SCOPE:
@ -126,7 +126,7 @@ func (e *executor) executeRemoveToken(ctx context.Context, ast *sql.RemoveTokenS
// Remove the token definition
tkey := &keys.ST{KV: KV, NS: e.ns, DB: e.db, SC: ast.What.VA, TK: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, tkey.Encode(), 0)
_, err = e.tx.ClrP(ctx, tkey.Encode(), 0)
}
@ -142,7 +142,7 @@ func (e *executor) executeRemoveScope(ctx context.Context, ast *sql.RemoveScopeS
// Remove the scope definition
skey := &keys.SC{KV: KV, NS: e.ns, DB: e.db, SC: ast.Name.VA}
_, err = e.dbo.ClrP(ctx, skey.Encode(), 0)
_, err = e.tx.ClrP(ctx, skey.Encode(), 0)
return
@ -156,11 +156,11 @@ func (e *executor) executeRemoveEvent(ctx context.Context, ast *sql.RemoveEventS
for _, TB := range ast.What {
e.dbo.DelEV(e.ns, e.db, TB.TB, ast.Name.VA)
e.tx.DelEV(e.ns, e.db, TB.TB, ast.Name.VA)
// Remove the event definition
ekey := &keys.EV{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, EV: ast.Name.VA}
if _, err = e.dbo.ClrP(ctx, ekey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, ekey.Encode(), 0); err != nil {
return nil, err
}
@ -178,11 +178,11 @@ func (e *executor) executeRemoveField(ctx context.Context, ast *sql.RemoveFieldS
for _, TB := range ast.What {
e.dbo.DelFD(e.ns, e.db, TB.TB, ast.Name.VA)
e.tx.DelFD(e.ns, e.db, TB.TB, ast.Name.VA)
// Remove the field definition
fkey := &keys.FD{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, FD: ast.Name.VA}
if _, err = e.dbo.ClrP(ctx, fkey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, fkey.Encode(), 0); err != nil {
return nil, err
}
@ -200,17 +200,17 @@ func (e *executor) executeRemoveIndex(ctx context.Context, ast *sql.RemoveIndexS
for _, TB := range ast.What {
e.dbo.DelIX(e.ns, e.db, TB.TB, ast.Name.VA)
e.tx.DelIX(e.ns, e.db, TB.TB, ast.Name.VA)
// Remove the index definition
ikey := &keys.IX{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, IX: ast.Name.VA}
if _, err = e.dbo.ClrP(ctx, ikey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, ikey.Encode(), 0); err != nil {
return nil, err
}
// Remove the index resource data
dkey := &keys.Index{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB, IX: ast.Name.VA, FD: keys.Ignore}
if _, err = e.dbo.ClrP(ctx, dkey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, dkey.Encode(), 0); err != nil {
return nil, err
}
@ -228,23 +228,23 @@ func (e *executor) executeRemoveTable(ctx context.Context, ast *sql.RemoveTableS
for _, TB := range ast.What {
e.dbo.DelTB(e.ns, e.db, TB.TB)
e.tx.DelTB(e.ns, e.db, TB.TB)
tb, err := e.dbo.GetTB(ctx, e.ns, e.db, TB.TB)
tb, err := e.tx.GetTB(ctx, e.ns, e.db, TB.TB)
if err != nil {
return nil, err
}
// Remove the table definition
tkey := &keys.TB{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB}
_, err = e.dbo.Clr(ctx, tkey.Encode())
_, err = e.tx.Clr(ctx, tkey.Encode())
if err != nil {
return nil, err
}
// Remove the table resource data
dkey := &keys.Table{KV: KV, NS: e.ns, DB: e.db, TB: TB.TB}
_, err = e.dbo.ClrP(ctx, dkey.Encode(), 0)
_, err = e.tx.ClrP(ctx, dkey.Encode(), 0)
if err != nil {
return nil, err
}
@ -255,7 +255,7 @@ func (e *executor) executeRemoveTable(ctx context.Context, ast *sql.RemoveTableS
// Remove the foreign table definition
tkey := &keys.FT{KV: KV, NS: e.ns, DB: e.db, TB: FT.TB, FT: TB.TB}
if _, err = e.dbo.ClrP(ctx, tkey.Encode(), 0); err != nil {
if _, err = e.tx.ClrP(ctx, tkey.Encode(), 0); err != nil {
return nil, err
}

View file

@ -23,6 +23,7 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/data"
"github.com/abcum/surreal/util/keys"
@ -150,7 +151,7 @@ func (s *socket) check(e *executor, ctx context.Context, ns, db, tb string) (err
// otherwise, the scoped authentication
// request can not do anything.
_, err = e.dbo.GetNS(ctx, ns)
_, err = e.tx.GetNS(ctx, ns)
if err != nil {
return err
}
@ -159,7 +160,7 @@ func (s *socket) check(e *executor, ctx context.Context, ns, db, tb string) (err
// otherwise, the scoped authentication
// request can not do anything.
_, err = e.dbo.GetDB(ctx, ns, db)
_, err = e.tx.GetDB(ctx, ns, db)
if err != nil {
return err
}
@ -168,7 +169,7 @@ func (s *socket) check(e *executor, ctx context.Context, ns, db, tb string) (err
// otherwise, the scoped authentication
// request can not do anything.
tbv, err = e.dbo.GetTB(ctx, ns, db, tb)
tbv, err = e.tx.GetTB(ctx, ns, db, tb)
if err != nil {
return err
}
@ -192,7 +193,7 @@ func (s *socket) deregister(id string) {
ctx := context.Background()
txn, _ := db.Begin(ctx, true)
txn, _ := kvs.Begin(ctx, true)
defer txn.Commit()
@ -261,14 +262,14 @@ func (s *socket) executeLive(e *executor, ctx context.Context, stm *sql.LiveStat
case *sql.Table:
key := &keys.LV{KV: KV, NS: stm.NS, DB: stm.DB, TB: what.TB, LV: stm.ID}
if _, err = e.dbo.Put(ctx, 0, key.Encode(), stm.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, key.Encode(), stm.Encode()); err != nil {
return nil, err
}
case *sql.Ident:
key := &keys.LV{KV: KV, NS: stm.NS, DB: stm.DB, TB: what.VA, LV: stm.ID}
if _, err = e.dbo.Put(ctx, 0, key.Encode(), stm.Encode()); err != nil {
if _, err = e.tx.Put(ctx, 0, key.Encode(), stm.Encode()); err != nil {
return nil, err
}
@ -320,11 +321,11 @@ func (s *socket) executeKill(e *executor, ctx context.Context, stm *sql.KillStat
case *sql.Table:
key := &keys.LV{KV: KV, NS: qry.NS, DB: qry.DB, TB: what.TB, LV: qry.ID}
_, err = e.dbo.Clr(ctx, key.Encode())
_, err = e.tx.Clr(ctx, key.Encode())
case *sql.Ident:
key := &keys.LV{KV: KV, NS: qry.NS, DB: qry.DB, TB: what.VA, LV: qry.ID}
_, err = e.dbo.Clr(ctx, key.Encode())
_, err = e.tx.Clr(ctx, key.Encode())
}

View file

@ -51,7 +51,7 @@ func (d *document) table(ctx context.Context, when method) (err error) {
// specified for this table, and
// update values which have changed.
fts, err := d.i.e.dbo.AllFT(ctx, d.key.NS, d.key.DB, d.key.TB)
fts, err := d.i.e.tx.AllFT(ctx, d.key.NS, d.key.DB, d.key.TB)
if err != nil {
return err
}

6
go.mod
View file

@ -2,11 +2,14 @@ module github.com/abcum/surreal
go 1.13
replace github.com/abcum/fibre => /Users/tobie/Repositories/fibre
require (
github.com/abcum/bump v0.0.0-20190929092354-46a9c9dbf9ab
github.com/abcum/cork v0.0.0-20190929093632-f45e788b8f1b
github.com/abcum/fibre v0.0.0-20191003170635-45f18bd55f9a
github.com/abcum/rixxdb v0.0.0-20191008002349-42eb662df538
github.com/dgraph-io/ristretto v0.0.0-20191114170855-99d1bbbf28e6
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/elithrar/simple-scrypt v1.3.0
github.com/gorilla/websocket v1.4.1
@ -21,7 +24,8 @@ require (
github.com/sirupsen/logrus v1.4.2
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
github.com/spf13/cobra v0.0.5
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8
github.com/stackimpact/stackimpact-go v2.3.10+incompatible
github.com/ugorji/go/codec v1.1.7
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0
golang.org/x/text v0.3.2

37
go.sum
View file

@ -1,21 +1,27 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/abcum/bump v0.0.0-20190929092354-46a9c9dbf9ab h1:S7Bp0inII96zGek8nipouocogy9xjMcJuDUKIb/+jkw=
github.com/abcum/bump v0.0.0-20190929092354-46a9c9dbf9ab/go.mod h1:nhz3F2Uy1ra958EB0V4uR1WjTdLmpiznz7sqMdRBi7A=
github.com/abcum/cork v0.0.0-20190929093632-f45e788b8f1b h1:R/fzwNDZALJjuU9zjtJ8z1YTp03xkePY7ITjfaTppbA=
github.com/abcum/cork v0.0.0-20190929093632-f45e788b8f1b/go.mod h1:t54olPax+YxSe0VIdutFPcEupQhkg7Y3QA8FzxNe6Po=
github.com/abcum/fibre v0.0.0-20191003170635-45f18bd55f9a h1:w7vwArRjHlY/Kvi4f86O0nhQxSbC1ovnZ+Yvla7aUjI=
github.com/abcum/fibre v0.0.0-20191003170635-45f18bd55f9a/go.mod h1:CPo8U5dmWBEajd6U7ozAQRp0b1zbuRkaAyZJneBZ63g=
github.com/abcum/rixxdb v0.0.0-20191008002349-42eb662df538 h1:y1Qj5WC/jAYWRQt/z00RCUB7XgFm7K5ej7S6lqE9whA=
github.com/abcum/rixxdb v0.0.0-20191008002349-42eb662df538/go.mod h1:6lIALuvT453ADA/5AFRXGLDNcc3sqIvt4ISaKyPeTLg=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/ristretto v0.0.0-20191114170855-99d1bbbf28e6 h1:liDEMz8LbPxfuI8e/noprwccn6gZGv2rN1AgucbxjHs=
github.com/dgraph-io/ristretto v0.0.0-20191114170855-99d1bbbf28e6/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/elithrar/simple-scrypt v1.3.0 h1:KIlOlxdoQf9JWKl5lMAJ28SY2URB0XTRDn2TckyzAZg=
github.com/elithrar/simple-scrypt v1.3.0/go.mod h1:U2XQRI95XHY0St410VE3UjT7vuKb1qPwrl/EJwEqnZo=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -32,11 +38,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -47,9 +48,11 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/newrelic/go-agent v2.13.0+incompatible h1:Dl6m75MHAzfB0kicv9GiLxzQatRjTLUAdrnYyoT8s4M=
github.com/newrelic/go-agent v2.13.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
github.com/ory/graceful v0.1.1 h1:zx+8tDObLPrG+7Tc8jKYlXsqWnLtOQA1IZ/FAAKHMXU=
github.com/ory/graceful v0.1.1/go.mod h1:zqu70l95WrKHF4AZ6tXHvAqAvpY6M7g6ttaAVcMm7KU=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.3.0 h1:OQIvuDgm00gWVWGTf4m4mCt6W1/0YqU7Ntg0mySWgaI=
github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -61,6 +64,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc=
github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
@ -69,6 +74,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
@ -77,11 +84,17 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stackimpact/stackimpact-go v2.3.10+incompatible h1:ySvQuFaxqpFEMq/IZElqt1nvYgWMoRpkQ9VAzZoDpJ0=
github.com/stackimpact/stackimpact-go v2.3.10+incompatible/go.mod h1:Seecan0KCHJ0D5MYjIhx9TddZ0p53TicSrE9sBdovcU=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -89,7 +102,6 @@ golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -104,9 +116,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tylerb/graceful.v1 v1.2.15 h1:1JmOyhKqAyX3BgTXMI84LwT6FOJ4tP2N9e2kwTCM0nQ=
gopkg.in/tylerb/graceful.v1 v1.2.15/go.mod h1:yBhekWvR20ACXVObSSdD3u6S9DeSylanL2PAbAC/uJ8=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View file

@ -22,8 +22,6 @@ import (
"github.com/abcum/surreal/cnf"
)
var stores = make(map[string]func(*cnf.Options) (DB, error))
// DB represents a backing datastore.
type DS struct {
db DB
@ -80,10 +78,3 @@ func (ds *DS) Export(w io.Writer) (err error) {
func (ds *DS) Close() (err error) {
return ds.db.Close()
}
// Register registers a new database type with
// the kvs package, enabling it's use as a
// backing datastore within SurrealDB.
func Register(name string, constructor func(*cnf.Options) (DB, error)) {
stores[name] = constructor
}

77
kvs/main.go Normal file
View file

@ -0,0 +1,77 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package kvs
import (
"context"
"io"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/log"
)
var ds *DS
// Stores the different backend implementations
var stores = make(map[string]func(*cnf.Options) (DB, error))
// Setup sets up the connection with the data layer
func Setup(opts *cnf.Options) (err error) {
log.WithPrefix("kvs").Infof("Starting kvs storage at %s", opts.DB.Path)
ds, err = New(opts)
log.WithPrefix("kvs").Infof("Started kvs storage at %s", opts.DB.Path)
return
}
// Exit shuts down the connection with the data layer
func Exit(opts *cnf.Options) (err error) {
log.WithPrefix("kvs").Infof("Shutting down kvs storage at %s", opts.DB.Path)
return ds.Close()
}
// Begin begins a new read / write transaction
// with the underlying database, and returns
// the transaction, or any error which occured.
func Begin(ctx context.Context, writable bool) (txn TX, err error) {
return ds.db.Begin(ctx, writable)
}
// Import loads database operations from a reader.
// This can be used to playback a database snapshot
// into an already running database.
func Import(r io.Reader) (err error) {
return ds.db.Import(r)
}
// Export saves all database operations to a writer.
// This can be used to save a database snapshot
// to a secondary file or stream.
func Export(w io.Writer) (err error) {
return ds.db.Export(w)
}
// Close closes the underlying rixxdb / dendrodb
// database connection, enabling the underlying
// database to clean up remainging transactions.
func Close() (err error) {
return ds.db.Close()
}
// Register registers a new database type with
// the kvs package, enabling it's use as a
// backing datastore within SurrealDB.
func Register(name string, constructor func(*cnf.Options) (DB, error)) {
stores[name] = constructor
}

View file

@ -30,6 +30,9 @@ type TX interface {
ClrP(context.Context, []byte, uint64) ([]KV, error)
ClrR(context.Context, []byte, []byte, uint64) ([]KV, error)
Put(context.Context, int64, []byte, []byte) (KV, error)
PutC(context.Context, int64, []byte, []byte, []byte) (KV, error)
Get(context.Context, int64, []byte) (KV, error)
GetP(context.Context, int64, []byte, uint64) ([]KV, error)
GetR(context.Context, int64, []byte, []byte, uint64) ([]KV, error)
@ -38,7 +41,4 @@ type TX interface {
DelC(context.Context, int64, []byte, []byte) (KV, error)
DelP(context.Context, int64, []byte, uint64) ([]KV, error)
DelR(context.Context, int64, []byte, []byte, uint64) ([]KV, error)
Put(context.Context, int64, []byte, []byte) (KV, error)
PutC(context.Context, int64, []byte, []byte, []byte) (KV, error)
}

View file

@ -22,6 +22,8 @@ import (
"github.com/pkg/profile"
"github.com/abcum/surreal/cli"
"github.com/stackimpact/stackimpact-go"
)
func main() {
@ -35,6 +37,11 @@ func main() {
defer profile.Start(profile.BlockProfile, profile.ProfilePath("."), profile.NoShutdownHook).Stop()
}
stackimpact.Start(stackimpact.Options{
AgentKey: "3326cc7b7c7de70cf2a29f8320c42c31149f39da",
AppName: "Surreal",
})
runtime.GOMAXPROCS(runtime.NumCPU())
cli.Init()

View file

@ -1,936 +0,0 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package mem
import (
"sync"
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
type Cache struct {
kvs.TX
lock sync.RWMutex
data map[string]interface{}
locks struct {
ns sync.RWMutex
db sync.RWMutex
tb sync.RWMutex
}
}
func New() (c *Cache) {
return &Cache{
data: make(map[string]interface{}),
}
}
func NewWithTX(tx kvs.TX) (c *Cache) {
return &Cache{
TX: tx,
data: make(map[string]interface{}),
}
}
func (c *Cache) Reset() {
c.TX = nil
}
func (c *Cache) get(key keys.Key) (out interface{}, ok bool) {
c.lock.RLock()
out, ok = c.data[key.String()]
c.lock.RUnlock()
return
}
func (c *Cache) put(key keys.Key, val interface{}) {
c.lock.Lock()
c.data[key.String()] = val
c.lock.Unlock()
}
func (c *Cache) del(key keys.Key) {
c.lock.Lock()
delete(c.data, key.String())
c.lock.Unlock()
}
// --------------------------------------------------
func (c *Cache) AllNS(ctx context.Context) (out []*sql.DefineNamespaceStatement, err error) {
var kvs []kvs.KV
c.locks.ns.RLock()
defer c.locks.ns.RUnlock()
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineNamespaceStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetNS(ctx context.Context, ns string) (val *sql.DefineNamespaceStatement, err error) {
var kv kvs.KV
c.locks.ns.RLock()
defer c.locks.ns.RUnlock()
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: ns}
if out, ok := c.get(key); ok {
return out.(*sql.DefineNamespaceStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNSNotFound
}
val = &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) AddNS(ctx context.Context, ns string) (val *sql.DefineNamespaceStatement, err error) {
var kv kvs.KV
c.locks.ns.Lock()
defer c.locks.ns.Unlock()
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: ns}
if out, ok := c.get(key); ok {
return out.(*sql.DefineNamespaceStatement), nil
}
if kv, _ = c.TX.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
val = &sql.DefineNamespaceStatement{Name: sql.NewIdent(ns)}
c.TX.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
c.put(key, val)
return
}
func (c *Cache) DelNS(ns string) {
c.del(&keys.NS{KV: cnf.Settings.DB.Base, NS: keys.Ignore})
c.del(&keys.NS{KV: cnf.Settings.DB.Base, NS: ns})
}
// --------------------------------------------------
func (c *Cache) AllNT(ctx context.Context, ns string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.NT{KV: cnf.Settings.DB.Base, NS: ns, TK: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetNT(ctx context.Context, ns, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.NT{KV: cnf.Settings.DB.Base, NS: ns, TK: tk}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllNU(ctx context.Context, ns string) (out []*sql.DefineLoginStatement, err error) {
var kvs []kvs.KV
key := &keys.NU{KV: cnf.Settings.DB.Base, NS: ns, US: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineLoginStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetNU(ctx context.Context, ns, us string) (val *sql.DefineLoginStatement, err error) {
var kv kvs.KV
key := &keys.NU{KV: cnf.Settings.DB.Base, NS: ns, US: us}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNUNotFound
}
val = &sql.DefineLoginStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllDB(ctx context.Context, ns string) (out []*sql.DefineDatabaseStatement, err error) {
var kvs []kvs.KV
c.locks.db.RLock()
defer c.locks.db.RUnlock()
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineDatabaseStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetDB(ctx context.Context, ns, db string) (val *sql.DefineDatabaseStatement, err error) {
var kv kvs.KV
c.locks.db.RLock()
defer c.locks.db.RUnlock()
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: db}
if out, ok := c.get(key); ok {
return out.(*sql.DefineDatabaseStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDBNotFound
}
val = &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) AddDB(ctx context.Context, ns, db string) (val *sql.DefineDatabaseStatement, err error) {
if _, err = c.AddNS(ctx, ns); err != nil {
return
}
var kv kvs.KV
c.locks.db.Lock()
defer c.locks.db.Unlock()
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: db}
if out, ok := c.get(key); ok {
return out.(*sql.DefineDatabaseStatement), nil
}
if kv, _ = c.TX.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
val = &sql.DefineDatabaseStatement{Name: sql.NewIdent(db)}
c.TX.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
c.put(key, val)
return
}
func (c *Cache) DelDB(ns, db string) {
c.del(&keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: keys.Ignore})
c.del(&keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: db})
}
// --------------------------------------------------
func (c *Cache) AllDT(ctx context.Context, ns, db string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.DT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TK: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetDT(ctx context.Context, ns, db, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.DT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TK: tk}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllDU(ctx context.Context, ns, db string) (out []*sql.DefineLoginStatement, err error) {
var kvs []kvs.KV
key := &keys.DU{KV: cnf.Settings.DB.Base, NS: ns, DB: db, US: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineLoginStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetDU(ctx context.Context, ns, db, us string) (val *sql.DefineLoginStatement, err error) {
var kv kvs.KV
key := &keys.DU{KV: cnf.Settings.DB.Base, NS: ns, DB: db, US: us}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDUNotFound
}
val = &sql.DefineLoginStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllSC(ctx context.Context, ns, db string) (out []*sql.DefineScopeStatement, err error) {
var kvs []kvs.KV
key := &keys.SC{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineScopeStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetSC(ctx context.Context, ns, db, sc string) (val *sql.DefineScopeStatement, err error) {
var kv kvs.KV
key := &keys.SC{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorSCNotFound
}
val = &sql.DefineScopeStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllST(ctx context.Context, ns, db, sc string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.ST{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc, TK: keys.Ignore}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (c *Cache) GetST(ctx context.Context, ns, db, sc, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.ST{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc, TK: tk}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorSTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}
// --------------------------------------------------
func (c *Cache) AllTB(ctx context.Context, ns, db string) (out []*sql.DefineTableStatement, err error) {
var kvs []kvs.KV
c.locks.tb.RLock()
defer c.locks.tb.RUnlock()
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineTableStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTableStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetTB(ctx context.Context, ns, db, tb string) (val *sql.DefineTableStatement, err error) {
var kv kvs.KV
c.locks.tb.RLock()
defer c.locks.tb.RUnlock()
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb}
if out, ok := c.get(key); ok {
return out.(*sql.DefineTableStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorTBNotFound
}
val = &sql.DefineTableStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) AddTB(ctx context.Context, ns, db, tb string) (val *sql.DefineTableStatement, err error) {
if _, err = c.AddDB(ctx, ns, db); err != nil {
return
}
var kv kvs.KV
c.locks.tb.Lock()
defer c.locks.tb.Unlock()
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb}
if out, ok := c.get(key); ok {
return out.(*sql.DefineTableStatement), nil
}
if kv, _ = c.TX.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineTableStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
val = &sql.DefineTableStatement{Name: sql.NewIdent(tb)}
c.TX.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
c.put(key, val)
return
}
func (c *Cache) DelTB(ns, db, tb string) {
c.del(&keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: keys.Ignore})
c.del(&keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb})
}
// --------------------------------------------------
func (c *Cache) AllEV(ctx context.Context, ns, db, tb string) (out []*sql.DefineEventStatement, err error) {
var kvs []kvs.KV
key := &keys.EV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, EV: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineEventStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineEventStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetEV(ctx context.Context, ns, db, tb, ev string) (val *sql.DefineEventStatement, err error) {
var kv kvs.KV
key := &keys.EV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, EV: ev}
if out, ok := c.get(key); ok {
return out.(*sql.DefineEventStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorEVNotFound
}
val = &sql.DefineEventStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) DelEV(ns, db, tb, ev string) {
c.del(&keys.EV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, EV: keys.Ignore})
c.del(&keys.EV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, EV: ev})
}
// --------------------------------------------------
func (c *Cache) AllFD(ctx context.Context, ns, db, tb string) (out []*sql.DefineFieldStatement, err error) {
var kvs []kvs.KV
key := &keys.FD{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FD: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineFieldStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineFieldStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetFD(ctx context.Context, ns, db, tb, fd string) (val *sql.DefineFieldStatement, err error) {
var kv kvs.KV
key := &keys.FD{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FD: fd}
if out, ok := c.get(key); ok {
return out.(*sql.DefineFieldStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorFDNotFound
}
val = &sql.DefineFieldStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) DelFD(ns, db, tb, fd string) {
c.del(&keys.FD{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FD: keys.Ignore})
c.del(&keys.FD{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FD: fd})
}
// --------------------------------------------------
func (c *Cache) AllIX(ctx context.Context, ns, db, tb string) (out []*sql.DefineIndexStatement, err error) {
var kvs []kvs.KV
key := &keys.IX{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, IX: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineIndexStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineIndexStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetIX(ctx context.Context, ns, db, tb, ix string) (val *sql.DefineIndexStatement, err error) {
var kv kvs.KV
key := &keys.IX{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, IX: ix}
if out, ok := c.get(key); ok {
return out.(*sql.DefineIndexStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorIXNotFound
}
val = &sql.DefineIndexStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) DelIX(ns, db, tb, ix string) {
c.del(&keys.IX{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, IX: keys.Ignore})
c.del(&keys.IX{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, IX: ix})
}
// --------------------------------------------------
func (c *Cache) AllFT(ctx context.Context, ns, db, tb string) (out []*sql.DefineTableStatement, err error) {
var kvs []kvs.KV
key := &keys.FT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FT: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.DefineTableStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTableStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetFT(ctx context.Context, ns, db, tb, ft string) (val *sql.DefineTableStatement, err error) {
var kv kvs.KV
key := &keys.FT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FT: ft}
if out, ok := c.get(key); ok {
return out.(*sql.DefineTableStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorFTNotFound
}
val = &sql.DefineTableStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) DelFT(ns, db, tb, ft string) {
c.del(&keys.FT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FT: keys.Ignore})
c.del(&keys.FT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FT: ft})
}
// --------------------------------------------------
func (c *Cache) AllLV(ctx context.Context, ns, db, tb string) (out []*sql.LiveStatement, err error) {
var kvs []kvs.KV
key := &keys.LV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, LV: keys.Ignore}
if out, ok := c.get(key); ok {
return out.([]*sql.LiveStatement), nil
}
if kvs, err = c.TX.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.LiveStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
c.put(key, out)
return
}
func (c *Cache) GetLV(ctx context.Context, ns, db, tb, lv string) (val *sql.LiveStatement, err error) {
var kv kvs.KV
key := &keys.LV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, LV: lv}
if out, ok := c.get(key); ok {
return out.(*sql.LiveStatement), nil
}
if kv, err = c.TX.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorLVNotFound
}
val = &sql.LiveStatement{}
val.Decode(kv.Val())
c.put(key, val)
return
}
func (c *Cache) DelLV(ns, db, tb, lv string) {
c.del(&keys.LV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, LV: keys.Ignore})
c.del(&keys.LV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, LV: lv})
}

File diff suppressed because it is too large Load diff

View file

@ -18,5 +18,5 @@ package sql
//go:generate tmpl -file=kill.gen.json kill.gen.go.tmpl
//go:generate tmpl -file=rdwr.gen.json rdwr.gen.go.tmpl
//go:generate go get -u github.com/ugorji/go/codec/codecgen@v0.0.0-20181204163529-d75b2dcb6bc8
//go:generate go get -u github.com/ugorji/go/codec/codecgen
//go:generate codecgen -o ast.gen.go ast.go

107
txn/db.go Normal file
View file

@ -0,0 +1,107 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllDB(ctx context.Context, ns string) (out []*sql.DefineDatabaseStatement, err error) {
var kvs []kvs.KV
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetDB(ctx context.Context, ns, db string) (val *sql.DefineDatabaseStatement, err error) {
if out, ok := t.get(_db, db); ok {
return out.(*sql.DefineDatabaseStatement), nil
}
var kv kvs.KV
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: db}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDBNotFound
}
val = &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
t.set(_db, db, val)
return
}
func (t *TX) AddDB(ctx context.Context, ns, db string) (val *sql.DefineDatabaseStatement, err error) {
if out, ok := t.get(_db, db); ok {
return out.(*sql.DefineDatabaseStatement), nil
}
if _, err = t.AddNS(ctx, ns); err != nil {
return
}
var kv kvs.KV
key := &keys.DB{KV: cnf.Settings.DB.Base, NS: ns, DB: db}
if kv, _ = t.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineDatabaseStatement{}
val.Decode(kv.Val())
t.set(_db, db, val)
return
}
val = &sql.DefineDatabaseStatement{Name: sql.NewIdent(db)}
t.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
t.set(_db, db, val)
return
}
func (t *TX) DelDB(ns, db string) {
t.del(_db, db)
}

63
txn/dt.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllDT(ctx context.Context, ns, db string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.DT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TK: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetDT(ctx context.Context, ns, db, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.DT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TK: tk}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}

63
txn/du.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllDU(ctx context.Context, ns, db string) (out []*sql.DefineLoginStatement, err error) {
var kvs []kvs.KV
key := &keys.DU{KV: cnf.Settings.DB.Base, NS: ns, DB: db, US: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineLoginStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetDU(ctx context.Context, ns, db, us string) (val *sql.DefineLoginStatement, err error) {
var kv kvs.KV
key := &keys.DU{KV: cnf.Settings.DB.Base, NS: ns, DB: db, US: us}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorDUNotFound
}
val = &sql.DefineLoginStatement{}
val.Decode(kv.Val())
return
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package mem
package txn
import "errors"

56
txn/ev.go Normal file
View file

@ -0,0 +1,56 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllEV(ctx context.Context, ns, db, tb string) (out []*sql.DefineEventStatement, err error) {
if out, ok := t.get(_ev, tb); ok {
return out.([]*sql.DefineEventStatement), nil
}
var kvs []kvs.KV
key := &keys.EV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, EV: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineEventStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
t.set(_ev, tb, out)
return
}
func (t *TX) DelEV(ns, db, tb, ev string) {
t.del(_ev, tb)
}

56
txn/fd.go Normal file
View file

@ -0,0 +1,56 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllFD(ctx context.Context, ns, db, tb string) (out []*sql.DefineFieldStatement, err error) {
if out, ok := t.get(_fd, tb); ok {
return out.([]*sql.DefineFieldStatement), nil
}
var kvs []kvs.KV
key := &keys.FD{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FD: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineFieldStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
t.set(_fd, tb, out)
return
}
func (t *TX) DelFD(ns, db, tb, fd string) {
t.del(_fd, tb)
}

56
txn/ft.go Normal file
View file

@ -0,0 +1,56 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllFT(ctx context.Context, ns, db, tb string) (out []*sql.DefineTableStatement, err error) {
if out, ok := t.get(_ft, tb); ok {
return out.([]*sql.DefineTableStatement), nil
}
var kvs []kvs.KV
key := &keys.FT{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, FT: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTableStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
t.set(_ft, tb, out)
return
}
func (t *TX) DelFT(ns, db, tb, ft string) {
t.del(_ft, tb)
}

56
txn/ix.go Normal file
View file

@ -0,0 +1,56 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllIX(ctx context.Context, ns, db, tb string) (out []*sql.DefineIndexStatement, err error) {
if out, ok := t.get(_ix, tb); ok {
return out.([]*sql.DefineIndexStatement), nil
}
var kvs []kvs.KV
key := &keys.IX{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, IX: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineIndexStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
t.set(_ix, tb, out)
return
}
func (t *TX) DelIX(ns, db, tb, ix string) {
t.del(_ix, tb)
}

57
txn/lv.go Normal file
View file

@ -0,0 +1,57 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllLV(ctx context.Context, ns, db, tb string) (out []*sql.LiveStatement, err error) {
return
if out, ok := t.get(_lv, tb); ok {
return out.([]*sql.LiveStatement), nil
}
var kvs []kvs.KV
key := &keys.LV{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb, LV: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.LiveStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
t.set(_lv, tb, out)
return
}
func (t *TX) DelLV(ns, db, tb, lv string) {
t.del(_lv, tb)
}

103
txn/ns.go Normal file
View file

@ -0,0 +1,103 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllNS(ctx context.Context) (out []*sql.DefineNamespaceStatement, err error) {
var kvs []kvs.KV
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetNS(ctx context.Context, ns string) (val *sql.DefineNamespaceStatement, err error) {
if out, ok := t.get(_ns, ns); ok {
return out.(*sql.DefineNamespaceStatement), nil
}
var kv kvs.KV
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: ns}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNSNotFound
}
val = &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
t.set(_ns, ns, val)
return
}
func (t *TX) AddNS(ctx context.Context, ns string) (val *sql.DefineNamespaceStatement, err error) {
if out, ok := t.get(_ns, ns); ok {
return out.(*sql.DefineNamespaceStatement), nil
}
var kv kvs.KV
key := &keys.NS{KV: cnf.Settings.DB.Base, NS: ns}
if kv, _ = t.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineNamespaceStatement{}
val.Decode(kv.Val())
t.set(_ns, ns, val)
return
}
val = &sql.DefineNamespaceStatement{Name: sql.NewIdent(ns)}
t.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
t.set(_ns, ns, val)
return
}
func (t *TX) DelNS(ns string) {
t.del(_ns, ns)
}

63
txn/nt.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllNT(ctx context.Context, ns string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.NT{KV: cnf.Settings.DB.Base, NS: ns, TK: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetNT(ctx context.Context, ns, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.NT{KV: cnf.Settings.DB.Base, NS: ns, TK: tk}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}

63
txn/nu.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllNU(ctx context.Context, ns string) (out []*sql.DefineLoginStatement, err error) {
var kvs []kvs.KV
key := &keys.NU{KV: cnf.Settings.DB.Base, NS: ns, US: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineLoginStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetNU(ctx context.Context, ns, us string) (val *sql.DefineLoginStatement, err error) {
var kv kvs.KV
key := &keys.NU{KV: cnf.Settings.DB.Base, NS: ns, US: us}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorNUNotFound
}
val = &sql.DefineLoginStatement{}
val.Decode(kv.Val())
return
}

63
txn/sc.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllSC(ctx context.Context, ns, db string) (out []*sql.DefineScopeStatement, err error) {
var kvs []kvs.KV
key := &keys.SC{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineScopeStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetSC(ctx context.Context, ns, db, sc string) (val *sql.DefineScopeStatement, err error) {
var kv kvs.KV
key := &keys.SC{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorSCNotFound
}
val = &sql.DefineScopeStatement{}
val.Decode(kv.Val())
return
}

63
txn/st.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllST(ctx context.Context, ns, db, sc string) (out []*sql.DefineTokenStatement, err error) {
var kvs []kvs.KV
key := &keys.ST{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc, TK: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTokenStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetST(ctx context.Context, ns, db, sc, tk string) (val *sql.DefineTokenStatement, err error) {
var kv kvs.KV
key := &keys.ST{KV: cnf.Settings.DB.Base, NS: ns, DB: db, SC: sc, TK: tk}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorSTNotFound
}
val = &sql.DefineTokenStatement{}
val.Decode(kv.Val())
return
}

107
txn/tb.go Normal file
View file

@ -0,0 +1,107 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"context"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/util/keys"
)
func (t *TX) AllTB(ctx context.Context, ns, db string) (out []*sql.DefineTableStatement, err error) {
var kvs []kvs.KV
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: keys.Ignore}
if kvs, err = t.GetP(ctx, 0, key.Encode(), 0); err != nil {
return
}
for _, kv := range kvs {
val := &sql.DefineTableStatement{}
val.Decode(kv.Val())
out = append(out, val)
}
return
}
func (t *TX) GetTB(ctx context.Context, ns, db, tb string) (val *sql.DefineTableStatement, err error) {
if out, ok := t.get(_tb, tb); ok {
return out.(*sql.DefineTableStatement), nil
}
var kv kvs.KV
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb}
if kv, err = t.Get(ctx, 0, key.Encode()); err != nil {
return nil, err
}
if !kv.Exi() {
return nil, ErrorTBNotFound
}
val = &sql.DefineTableStatement{}
val.Decode(kv.Val())
t.set(_tb, tb, val)
return
}
func (t *TX) AddTB(ctx context.Context, ns, db, tb string) (val *sql.DefineTableStatement, err error) {
if out, ok := t.get(_tb, tb); ok {
return out.(*sql.DefineTableStatement), nil
}
if _, err = t.AddDB(ctx, ns, db); err != nil {
return
}
var kv kvs.KV
key := &keys.TB{KV: cnf.Settings.DB.Base, NS: ns, DB: db, TB: tb}
if kv, _ = t.Get(ctx, 0, key.Encode()); kv.Exi() {
val = &sql.DefineTableStatement{}
val.Decode(kv.Val())
t.set(_tb, tb, val)
return
}
val = &sql.DefineTableStatement{Name: sql.NewIdent(tb)}
t.PutC(ctx, 0, key.Encode(), val.Encode(), nil)
t.set(_tb, tb, val)
return
}
func (t *TX) DelTB(ns, db, tb string) {
t.del(_tb, tb)
}

120
txn/txn.go Normal file
View file

@ -0,0 +1,120 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package txn
import (
"sync"
"context"
"github.com/abcum/surreal/kvs"
)
type symbol int8
const (
_ns symbol = iota
_db
_tb
_fd
_ix
_ev
_ft
_lv
_kv
)
// --------------------------------------------------
type TX struct {
kvs.TX
lock sync.RWMutex
data map[symbol]map[string]interface{}
}
func New(ctx context.Context, rw bool) (*TX, error) {
txn, err := kvs.Begin(ctx, rw)
if err != nil {
return nil, err
}
return &TX{TX: txn}, nil
}
// --------------------------------------------------
func (t *TX) mem(s symbol) {
t.lock.Lock()
if t.data == nil {
t.data = make(map[symbol]map[string]interface{}, 8)
}
if t.data[s] == nil {
t.data[s] = make(map[string]interface{}, 5)
}
t.lock.Unlock()
}
func (t *TX) del(s symbol, key string) {
t.mem(s)
t.lock.Lock()
delete(t.data[s], key)
t.lock.Unlock()
}
func (t *TX) set(s symbol, key string, val interface{}) {
t.mem(s)
t.lock.Lock()
t.data[s][key] = val
t.lock.Unlock()
}
func (t *TX) get(s symbol, key string) (val interface{}, ok bool) {
t.mem(s)
t.lock.RLock()
val, ok = t.data[s][key]
t.lock.RUnlock()
return
}
// --------------------------------------------------
/*func (t *TX) _put(key []byte, val interface{}) {
t.mem(_kv)
t.lock.Lock()
t.data[_kv][string(key)] = val
t.lock.Unlock()
}
func (t *TX) _get(key []byte) (val interface{}, ok bool) {
t.mem(_kv)
t.lock.RLock()
val, ok = t.data[_kv][string(key)]
t.lock.RUnlock()
return
}
func (t *TX) Get(ctx context.Context, ver int64, key []byte) (kvs.KV, error) {
if kv, ok := t._get(key); ok {
fmt.Println(key)
return kv.(kvs.KV), nil
}
kv, err := t.TX.Get(ctx, ver, key)
t._put(key, kv)
return kv, err
}*/

View file

@ -17,8 +17,8 @@ package fncs
import (
"context"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
)
func batch(ctx context.Context, args ...interface{}) (interface{}, error) {
@ -27,7 +27,7 @@ func batch(ctx context.Context, args ...interface{}) (interface{}, error) {
id, _ := ensureSlice(args[1])
if len(tb) == 0 {
return nil, mem.ErrorTBNotFound
return nil, txn.ErrorTBNotFound
}
return sql.NewBatch(tb, id), nil

View file

@ -17,8 +17,8 @@ package fncs
import (
"context"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
)
func model(ctx context.Context, args ...interface{}) (interface{}, error) {
@ -26,7 +26,7 @@ func model(ctx context.Context, args ...interface{}) (interface{}, error) {
tb, _ := ensureString(args[0])
if len(tb) == 0 {
return nil, mem.ErrorTBNotFound
return nil, txn.ErrorTBNotFound
}
switch len(args) {

View file

@ -17,8 +17,8 @@ package fncs
import (
"context"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
)
func table(ctx context.Context, args ...interface{}) (interface{}, error) {
@ -26,7 +26,7 @@ func table(ctx context.Context, args ...interface{}) (interface{}, error) {
tb, _ := ensureString(args[0])
if len(tb) == 0 {
return nil, mem.ErrorTBNotFound
return nil, txn.ErrorTBNotFound
}
return sql.NewTable(tb), nil

View file

@ -17,8 +17,8 @@ package fncs
import (
"context"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
)
func thing(ctx context.Context, args ...interface{}) (interface{}, error) {
@ -26,7 +26,7 @@ func thing(ctx context.Context, args ...interface{}) (interface{}, error) {
tb, _ := ensureString(args[0])
if len(tb) == 0 {
return nil, mem.ErrorTBNotFound
return nil, txn.ErrorTBNotFound
}
return sql.NewThing(tb, args[1]), nil

View file

@ -26,9 +26,8 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/db"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/websocket"
)
@ -260,7 +259,7 @@ func checkBasics(c *fibre.Context, info string, callback func() error) (err erro
func checkBearer(c *fibre.Context, info string, callback func() error) (err error) {
var txn kvs.TX
var tx *txn.TX
var res []*db.Response
var vars jwt.MapClaims
var nsk, dbk, sck, tkk, usk, tbk, idk bool
@ -268,22 +267,18 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
// Start a new read transaction.
if txn, err = db.Begin(false); err != nil {
if tx, err = txn.New(c.Context(), false); err != nil {
return fibre.NewHTTPError(500)
}
// Ensure the transaction closes.
defer txn.Cancel()
defer tx.Cancel()
// Get the current context.
ctx := c.Context()
// Setup the kvs layer cache.
cache := mem.NewWithTX(txn)
// Reset the auth data first.
auth := c.Get(varKeyAuth).(*cnf.Auth).Reset()
@ -314,7 +309,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
if nsk && dbk && sck && tkk {
scp, err := cache.GetSC(ctx, nsv, dbv, scv)
scp, err := tx.GetSC(ctx, nsv, dbv, scv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}
@ -362,7 +357,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
}
if tkv != "default" {
key, err := cache.GetST(ctx, nsv, dbv, scv, tkv)
key, err := tx.GetST(ctx, nsv, dbv, scv, tkv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}
@ -379,7 +374,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
} else if nsk && dbk && tkk {
if tkv != "default" {
key, err := cache.GetDT(ctx, nsv, dbv, tkv)
key, err := tx.GetDT(ctx, nsv, dbv, tkv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}
@ -389,7 +384,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
auth.Kind = cnf.AuthDB
return key.Code, nil
} else if usk {
usr, err := cache.GetDU(ctx, nsv, dbv, usv)
usr, err := tx.GetDU(ctx, nsv, dbv, usv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}
@ -400,7 +395,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
} else if nsk && tkk {
if tkv != "default" {
key, err := cache.GetNT(ctx, nsv, tkv)
key, err := tx.GetNT(ctx, nsv, tkv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}
@ -410,7 +405,7 @@ func checkBearer(c *fibre.Context, info string, callback func() error) (err erro
auth.Kind = cnf.AuthNS
return key.Code, nil
} else if usk {
usr, err := cache.GetNU(ctx, nsv, usv)
usr, err := tx.GetNU(ctx, nsv, usv)
if err != nil {
return nil, fmt.Errorf("Credentials failed")
}

View file

@ -24,14 +24,12 @@ func live() fibre.MiddlewareFunc {
return func(c *fibre.Context) (err error) {
if c.IsSocket() {
if id, ok := c.Get("id").(string); ok {
beg, end := db.Socket(c, id)
beg, end := db.Socket(c, c.Uniq())
beg()
err = h(c)
end()
return err
}
}
return h(c)

View file

@ -1,50 +0,0 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package web
import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
)
func logger(c *fibre.Context) (err error) {
if err := c.Upgrade(); err != nil {
return err
}
if c.Get("auth").(*cnf.Auth).Kind != cnf.AuthKV {
return fibre.NewHTTPError(401)
}
ws := &socket{
quit: make(chan struct{}),
msgs: make(chan interface{}),
}
streamer.wss.Store(c.Get("id"), ws)
for v := range ws.msgs {
err := c.Socket().SendJSON(v)
if err != nil {
ws.quit <- struct{}{}
}
}
streamer.wss.Delete(c.Get("id"))
return nil
}

View file

@ -77,14 +77,6 @@ func routes(s *fibre.Fibre) {
s.Rpc("/rpc", &rpc{})
// --------------------------------------------------
// Endpoints for authentication signup
// --------------------------------------------------
s.Get("/logs", func(c *fibre.Context) error {
return logger(c)
})
// --------------------------------------------------
// Endpoints for syncing data
// --------------------------------------------------

View file

@ -20,9 +20,8 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/db"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
"github.com/abcum/surreal/util/data"
"github.com/dgrijalva/jwt-go"
"golang.org/x/crypto/bcrypt"
@ -76,7 +75,7 @@ func signinInternal(c *fibre.Context, vars map[string]interface{}) (str string,
if nok && len(n) > 0 && dok && len(d) > 0 && sok && len(s) > 0 {
var ok bool
var txn kvs.TX
var tx *txn.TX
var doc *sql.Thing
var res []*db.Response
var exp *sql.SubExpression
@ -85,13 +84,13 @@ func signinInternal(c *fibre.Context, vars map[string]interface{}) (str string,
// Start a new read transaction.
if txn, err = db.Begin(false); err != nil {
if tx, err = txn.New(c.Context(), false); err != nil {
return str, fibre.NewHTTPError(500)
}
// Ensure the transaction closes.
defer txn.Cancel()
defer tx.Cancel()
// Get the current context.
@ -119,7 +118,7 @@ func signinInternal(c *fibre.Context, vars map[string]interface{}) (str string,
// Get the specified signin scope.
if scp, err = mem.NewWithTX(txn).GetSC(ctx, n, d, s); err != nil {
if scp, err = tx.GetSC(ctx, n, d, s); err != nil {
m := "Authentication scope does not exist"
return str, fibre.NewHTTPError(403).WithFields(f).WithMessage(m)
}
@ -337,17 +336,17 @@ func signinInternal(c *fibre.Context, vars map[string]interface{}) (str string,
func signinDB(c *fibre.Context, n, d, u, p string) (usr *sql.DefineLoginStatement, err error) {
var txn kvs.TX
var tx *txn.TX
// Start a new read transaction.
if txn, err = db.Begin(false); err != nil {
if tx, err = txn.New(c.Context(), false); err != nil {
return nil, fibre.NewHTTPError(500)
}
// Ensure the transaction closes.
defer txn.Cancel()
defer tx.Cancel()
// Get the current context.
@ -366,7 +365,7 @@ func signinDB(c *fibre.Context, n, d, u, p string) (usr *sql.DefineLoginStatemen
// Get the specified namespace login.
if usr, err = mem.NewWithTX(txn).GetDU(ctx, n, d, u); err != nil {
if usr, err = tx.GetDU(ctx, n, d, u); err != nil {
m := "Database login does not exist"
return nil, fibre.NewHTTPError(403).WithFields(f).WithMessage(m)
}
@ -384,17 +383,17 @@ func signinDB(c *fibre.Context, n, d, u, p string) (usr *sql.DefineLoginStatemen
func signinNS(c *fibre.Context, n, u, p string) (usr *sql.DefineLoginStatement, err error) {
var txn kvs.TX
var tx *txn.TX
// Start a new read transaction.
if txn, err = db.Begin(false); err != nil {
if tx, err = txn.New(c.Context(), false); err != nil {
return nil, fibre.NewHTTPError(500)
}
// Ensure the transaction closes.
defer txn.Cancel()
defer tx.Cancel()
// Get the current context.
@ -413,7 +412,7 @@ func signinNS(c *fibre.Context, n, u, p string) (usr *sql.DefineLoginStatement,
// Get the specified namespace login.
if usr, err = mem.NewWithTX(txn).GetNU(ctx, n, u); err != nil {
if usr, err = tx.GetNU(ctx, n, u); err != nil {
m := "Namespace login does not exist"
return nil, fibre.NewHTTPError(403).WithFields(f).WithMessage(m)
}

View file

@ -20,9 +20,8 @@ import (
"github.com/abcum/fibre"
"github.com/abcum/surreal/cnf"
"github.com/abcum/surreal/db"
"github.com/abcum/surreal/kvs"
"github.com/abcum/surreal/mem"
"github.com/abcum/surreal/sql"
"github.com/abcum/surreal/txn"
"github.com/abcum/surreal/util/data"
"github.com/dgrijalva/jwt-go"
)
@ -75,7 +74,7 @@ func signupInternal(c *fibre.Context, vars map[string]interface{}) (str string,
if nok && len(n) > 0 && dok && len(d) > 0 && sok && len(s) > 0 {
var ok bool
var txn kvs.TX
var tx *txn.TX
var doc *sql.Thing
var res []*db.Response
var exp *sql.SubExpression
@ -84,13 +83,13 @@ func signupInternal(c *fibre.Context, vars map[string]interface{}) (str string,
// Start a new read transaction.
if txn, err = db.Begin(false); err != nil {
if tx, err = txn.New(c.Context(), false); err != nil {
return str, fibre.NewHTTPError(500)
}
// Ensure the transaction closes.
defer txn.Cancel()
defer tx.Cancel()
// Get the current context.
@ -118,7 +117,7 @@ func signupInternal(c *fibre.Context, vars map[string]interface{}) (str string,
// Get the specified signin scope.
if scp, err = mem.NewWithTX(txn).GetSC(ctx, n, d, s); err != nil {
if scp, err = tx.GetSC(ctx, n, d, s); err != nil {
m := "Authentication scope does not exist"
return str, fibre.NewHTTPError(403).WithFields(f).WithMessage(m)
}

View file

@ -1,88 +0,0 @@
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package web
import (
"sync"
"github.com/abcum/surreal/log"
"github.com/sirupsen/logrus"
)
var streamer *stream
type stream struct {
wss sync.Map
}
type socket struct {
quit chan struct{}
msgs chan interface{}
}
func init() {
streamer = &stream{}
log.Instance().AddHook(streamer)
}
func (h *stream) Levels() []logrus.Level {
return logrus.AllLevels
}
func (h *stream) Fire(entry *logrus.Entry) error {
streamer.wss.Range(func(key, val interface{}) bool {
ws := val.(*socket)
select {
case <-ws.quit:
break
case ws.msgs <- h.Format(entry):
break
}
return true
})
return nil
}
func (h *stream) Format(entry *logrus.Entry) interface{} {
var keys = make(map[string]interface{})
var json = make(map[string]interface{})
for k, v := range entry.Data {
if k != "prefix" && k != "ctx" {
keys[k] = v
}
}
json["keys"] = keys
json["time"] = entry.Time
json["level"] = entry.Level.String()
json["message"] = entry.Message
json["prefix"], _ = entry.Data["prefix"]
return json
}

View file

@ -30,9 +30,10 @@ func Setup(opts *cnf.Options) (err error) {
s := fibre.Server()
routes(s)
s.SetWait("15s")
s.SetName("web")
s.SetIdleTimeout("60s")
s.SetReadTimeout("60s")
s.SetWriteTimeout("60s")
s.SetHTTPErrorHandler(errors)
s.Logger().SetLogger(log.Instance())
@ -41,7 +42,6 @@ func Setup(opts *cnf.Options) (err error) {
s.Use(mw.Uniq()) // Add uniq id
s.Use(mw.Fail()) // Catch panics
s.Use(mw.Logs()) // Log requests
s.Use(mw.Sock()) // Setup sockets
// Add cors headers
@ -82,10 +82,6 @@ func Setup(opts *cnf.Options) (err error) {
s.Use(live())
// Compress responses
s.Use(mw.Gzip())
// Redirect non-https
s.Use(mw.Secure(&mw.SecureOpts{
@ -111,10 +107,7 @@ func Setup(opts *cnf.Options) (err error) {
}
// Exit tears down the server gracefully
func Exit() (err error) {
log.WithPrefix("web").Infof("Gracefully shutting down %s protocol", "web")
func Exit(opts *cnf.Options) (err error) {
log.WithPrefix("web").Infof("Shutting down web server on %s", opts.Conn)
return
}