diff --git a/db/define.go b/db/define.go index 1c492ba6..72c7c0a0 100644 --- a/db/define.go +++ b/db/define.go @@ -98,7 +98,7 @@ func executeDefineRulesStatement(txn kvs.TX, ast *sql.DefineRulesStatement) (out // Set the field definition rkey := &keys.RU{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, RU: RU} - if err := txn.Put(rkey.Encode(), pack.ToBINC(ast)); err != nil { + if err := txn.Put(rkey.Encode(), pack.Encode(ast)); err != nil { return nil, err } @@ -147,7 +147,7 @@ func executeDefineFieldStatement(txn kvs.TX, ast *sql.DefineFieldStatement) (out // Set the field definition fkey := &keys.FD{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, FD: ast.Name} - if err := txn.Put(fkey.Encode(), pack.ToBINC(ast)); err != nil { + if err := txn.Put(fkey.Encode(), pack.Encode(ast)); err != nil { return nil, err } @@ -194,7 +194,7 @@ func executeDefineIndexStatement(txn kvs.TX, ast *sql.DefineIndexStatement) (out // Set the index definition ikey := &keys.IX{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: TB, IX: ast.Name} - if err := txn.Put(ikey.Encode(), pack.ToBINC(ast)); err != nil { + if err := txn.Put(ikey.Encode(), pack.Encode(ast)); err != nil { return nil, err } diff --git a/util/data/data.go b/util/data/data.go index b383b4f9..32656ceb 100644 --- a/util/data/data.go +++ b/util/data/data.go @@ -57,13 +57,13 @@ func (d *Doc) JSON() (data []byte) { // Encode encodes the data object to a byte slice. func (d *Doc) Encode() (dst []byte) { - dst = pack.ToBINC(d.data) + dst = pack.Encode(&d.data) return } // Decode decodes the byte slice into a data object. func (d *Doc) Decode(src []byte) *Doc { - pack.FromBINC(src, d.data) + pack.Decode(src, &d.data) return d } diff --git a/util/item/item.go b/util/item/item.go index 249e6c56..b508c169 100644 --- a/util/item/item.go +++ b/util/item/item.go @@ -75,7 +75,7 @@ func (this *Doc) getRules() { key := new(keys.RU) key.Decode(kv.Key()) if str, ok := key.RU.(string); ok { - pack.FromBINC(kv.Val(), &rul) + pack.Decode(kv.Val(), &rul) this.rules[str] = &rul } } @@ -92,7 +92,7 @@ func (this *Doc) getFields() { for _, kv := range rng { var fld sql.DefineFieldStatement - pack.FromBINC(kv.Val(), &fld) + pack.Decode(kv.Val(), &fld) this.fields = append(this.fields, &fld) } @@ -108,7 +108,7 @@ func (this *Doc) getIndexs() { for _, kv := range rng { var idx sql.DefineIndexStatement - pack.FromBINC(kv.Val(), &idx) + pack.Decode(kv.Val(), &idx) this.indexs = append(this.indexs, &idx) } diff --git a/util/pack/pack.go b/util/pack/pack.go index 83cb4d13..2e6a80fc 100644 --- a/util/pack/pack.go +++ b/util/pack/pack.go @@ -15,9 +15,12 @@ package pack import ( + "bytes" "reflect" "time" + "encoding/gob" + "github.com/ugorji/go/codec" "github.com/abcum/surreal/sql" @@ -30,15 +33,44 @@ var mh codec.MsgpackHandle func init() { - // JSONHandle - + // GOB + gob.Register(time.Time{}) jh.Canonical = true + gob.Register([]interface{}{}) + gob.Register(map[string]interface{}{}) + gob.Register(sql.Null{}) + gob.Register(sql.Void{}) + gob.Register(sql.Empty{}) + gob.Register(sql.Field{}) + gob.Register(sql.Group{}) + gob.Register(sql.Order{}) + gob.Register(sql.Ident{}) + gob.Register(sql.Table{}) + gob.Register(sql.Thing{}) + gob.Register(sql.DiffExpression{}) + gob.Register(sql.MergeExpression{}) + gob.Register(sql.ContentExpression{}) + gob.Register(sql.SelectStatement{}) + gob.Register(sql.CreateStatement{}) + gob.Register(sql.UpdateStatement{}) + gob.Register(sql.ModifyStatement{}) + gob.Register(sql.DeleteStatement{}) + gob.Register(sql.RelateStatement{}) + gob.Register(sql.RecordStatement{}) + gob.Register(sql.DefineViewStatement{}) + gob.Register(sql.DefineTableStatement{}) + gob.Register(sql.DefineRulesStatement{}) + gob.Register(sql.DefineFieldStatement{}) + gob.Register(sql.DefineIndexStatement{}) + + // JSON + jh.CheckCircularRef = false jh.AsSymbols = codec.AsSymbolDefault jh.SliceType = reflect.TypeOf([]interface{}(nil)) jh.MapType = reflect.TypeOf(map[string]interface{}(nil)) - // CBORHandle + // CBOR ch.Canonical = true ch.CheckCircularRef = false @@ -46,7 +78,7 @@ func init() { ch.SliceType = reflect.TypeOf([]interface{}(nil)) ch.MapType = reflect.TypeOf(map[string]interface{}(nil)) - // BINCHandle + // BINC bh.Canonical = true bh.CheckCircularRef = false @@ -66,8 +98,9 @@ func init() { bh.SetBytesExt(reflect.TypeOf(sql.Thing{}), 10, extSqlThing{}) bh.SetBytesExt(reflect.TypeOf(sql.Field{}), 11, extSqlField{}) bh.SetBytesExt(reflect.TypeOf(sql.Group{}), 12, extSqlGroup{}) + bh.SetBytesExt(reflect.TypeOf(sql.Order{}), 13, extSqlOrder{}) - // PACKHandle + // PACK mh.WriteExt = true mh.Canonical = true @@ -89,9 +122,23 @@ func init() { mh.SetBytesExt(reflect.TypeOf(sql.Thing{}), 10, extSqlThing{}) mh.SetBytesExt(reflect.TypeOf(sql.Field{}), 11, extSqlField{}) mh.SetBytesExt(reflect.TypeOf(sql.Group{}), 12, extSqlGroup{}) + mh.SetBytesExt(reflect.TypeOf(sql.Order{}), 13, extSqlOrder{}) } +// Encode encodes a data object into a GOB. +func Encode(src interface{}) (dst []byte) { + buf := bytes.NewBuffer(nil) + gob.NewEncoder(buf).Encode(src) + return buf.Bytes() +} + +// Decode decodes a GOB into a data object. +func Decode(src []byte, dst interface{}) { + buf := bytes.NewBuffer(src) + gob.NewDecoder(buf).Decode(dst) +} + // ToJSON encodes a data object to a JSON byte slice. func ToJSON(src interface{}) (dst []byte) { codec.NewEncoderBytes(&dst, &jh).Encode(src) diff --git a/util/pack/sql-order.go b/util/pack/sql-order.go new file mode 100644 index 00000000..088e280a --- /dev/null +++ b/util/pack/sql-order.go @@ -0,0 +1,44 @@ +// 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 pack + +import ( + "bytes" + "encoding/gob" + + "github.com/abcum/surreal/sql" +) + +type extSqlOrder struct{} + +func (x extSqlOrder) ReadExt(dst interface{}, src []byte) { + buf := bytes.NewBuffer(src) + dec := gob.NewDecoder(buf) + dec.Decode(dst.(*sql.Order)) + return +} + +func (x extSqlOrder) WriteExt(src interface{}) (dst []byte) { + buf := bytes.NewBuffer(nil) + switch obj := src.(type) { + case sql.Order: + enc := gob.NewEncoder(buf) + enc.Encode(obj) + case *sql.Order: + enc := gob.NewEncoder(buf) + enc.Encode(obj) + } + return buf.Bytes() +}