Skip to content

Commit

Permalink
schema loading
Browse files Browse the repository at this point in the history
  • Loading branch information
mialinx committed May 20, 2016
1 parent e680762 commit b516184
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 1 deletion.
29 changes: 28 additions & 1 deletion config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,37 @@ box.cfg{
wal_dir='xlog',
snap_dir='snap',
}

local s = box.schema.space.create('test', {if_not_exists = true})
local i = s:create_index('primary', {type = 'hash', parts = {1, 'NUM'}, if_not_exists = true})
s:create_index('primary', {type = 'hash', parts = {1, 'NUM'}, if_not_exists = true})
s:truncate()

local st = box.schema.space.create('schematest', {
id = 9991,
temporary = true,
if_not_exists = true,
field_count = 7,
format = {
[2] = {name = "name1"},
[3] = {type = "type2"},
[6] = {name = "name5", type = "str", more = "extra"},
},
})
st:create_index('primary', {
type = 'hash',
parts = {1, 'NUM'},
unique = true,
if_not_exists = true,
})
st:create_index('secondary', {
id = 3,
type = 'tree',
unique = false,
parts = { 2, 'num', 3, 'STR' },
if_not_exists = true,
})

s:truncate()
--box.schema.user.grant('guest', 'read,write,execute', 'universe')

-- auth testing: access control
Expand Down
6 changes: 6 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Connection struct {
r *bufio.Reader
w *bufio.Writer
mutex *sync.Mutex
Schema *Schema
requestId uint32
Greeting *Greeting
requests map[uint32]*Future
Expand Down Expand Up @@ -65,6 +66,11 @@ func Connect(addr string, opts Opts) (conn *Connection, err error) {
go conn.writer()
go conn.reader()

if err = conn.loadSchema(); err != nil {
conn.closeConnection(err)
return nil, err
}

return conn, err
}

Expand Down
132 changes: 132 additions & 0 deletions schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package tarantool

import (
_ "fmt"
)

type Schema struct {
Version uint
Spaces map[uint32]*Space
SpacesN map[string]*Space
}

type Space struct {
Id uint32
Name string
Engine string
Temporary bool
FieldsCount uint32
Fields map[uint32]*Field
FieldsN map[string]*Field
Indexes map[uint32]*Index
IndexesN map[string]*Index
}

type Field struct {
Id uint32
Name string
Type string
}

type Index struct {
Id uint32
Name string
Type string
Unique bool
Fields []*IndexField
}

type IndexField struct {
Id uint32
Type string
}

const (
maxSchemas = 10000
spaceSpId = 280
vspaceSpId = 281
indexSpId = 288
vindexSpId = 289
)

func (conn *Connection) loadSchema() (err error) {
var req *Request
var resp *Response

schema := new(Schema)
schema.Spaces = make(map[uint32]*Space)
schema.SpacesN = make(map[string]*Space)

// reload spaces
req = conn.NewRequest(SelectRequest)
req.fillSearch(spaceSpId, 0, []interface{}{})
req.fillIterator(0, maxSchemas, IterAll)
resp, err = req.perform()
if err != nil {
return err
}
for _, row := range resp.Data {
row := row.([]interface{})
space := new(Space)
space.Id = uint32(row[0].(uint64))
space.Name = row[2].(string)
space.Engine = row[3].(string)
space.FieldsCount = uint32(row[4].(uint64))
space.Temporary = bool(row[5].(string) == "temporary")
space.Fields = make(map[uint32]*Field)
space.FieldsN = make(map[string]*Field)
space.Indexes = make(map[uint32]*Index)
space.IndexesN = make(map[string]*Index)
for i, f := range row[6].([]interface{}) {
if f == nil {
continue
}
f := f.(map[interface{}]interface{})
field := new(Field)
field.Id = uint32(i)
if name, ok := f["name"]; ok && name != nil {
field.Name = name.(string)
}
if type_, ok := f["type"]; ok && type_ != nil {
field.Type = type_.(string)
}
space.Fields[field.Id] = field
if field.Name != "" {
space.FieldsN[field.Name] = field
}
}

schema.Spaces[space.Id] = space
schema.SpacesN[space.Name] = space
}

// reload indexes
req = conn.NewRequest(SelectRequest)
req.fillSearch(indexSpId, 0, []interface{}{})
req.fillIterator(0, maxSchemas, IterAll)
resp, err = req.perform()
if err != nil {
return err
}
for _, row := range resp.Data {
row := row.([]interface{})
index := new(Index)
index.Id = uint32(row[1].(uint64))
index.Name = row[2].(string)
index.Type = row[3].(string)
opts := row[4].(map[interface{}]interface{})
index.Unique = opts["unique"].(bool)
for _, f := range row[5].([]interface{}) {
f := f.([]interface{})
field := new(IndexField)
field.Id = uint32(f[0].(uint64))
field.Type = f[1].(string)
index.Fields = append(index.Fields, field)
}
spaceId := uint32(row[0].(uint64))
schema.Spaces[spaceId].Indexes[index.Id] = index
schema.Spaces[spaceId].IndexesN[index.Name] = index
}
conn.Schema = schema
return nil
}
141 changes: 141 additions & 0 deletions tarantool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,4 +492,145 @@ func TestClient(t *testing.T) {
if val != 11 {
t.Errorf("5 + 6 == 11, but got %v", val)
}

// Schema
schema := conn.Schema
if schema.Spaces == nil {
t.Errorf("schema.Spaces is nil")
}
if schema.SpacesN == nil {
t.Errorf("schema.SpacesN is nil")
}
var space, space2 *Space
var ok bool
if space, ok = schema.Spaces[9991]; !ok {
t.Errorf("space with id = 9991 was not found in schema.Spaces")
}
if space2, ok = schema.SpacesN["schematest"]; !ok {
t.Errorf("space with name 'schematest' was not found in schema.Spaces")
}
if space != space2 {
t.Errorf("space with id = 9991 and space with name schematest are different")
}
if space.Id != 9991 {
t.Errorf("space 9991 has incorrect Id")
}
if space.Name != "schematest" {
t.Errorf("space 9991 has incorrect Name")
}
if !space.Temporary {
t.Errorf("space 9991 should be temporary")
}
if space.Engine != "memtx" {
t.Errorf("space 9991 engine should be memtx")
}
if space.FieldsCount != 7 {
t.Errorf("space 9991 has incorrect fields count")
}

if space.Fields == nil {
t.Errorf("space.Fields is nill")
}
if space.FieldsN == nil {
t.Errorf("space.FieldsN is nill")
}
if len(space.Fields) != 3 {
t.Errorf("space.Fields len is incorrect")
}
if len(space.FieldsN) != 2 {
t.Errorf("space.FieldsN len is incorrect")
}

var field1, field2, field5, field1_, field5_ *Field
if field1, ok = space.Fields[1]; !ok {
t.Errorf("field id = 1 was not found")
}
if field2, ok = space.Fields[2]; !ok {
t.Errorf("field id = 2 was not found")
}
if field5, ok = space.Fields[5]; !ok {
t.Errorf("field id = 5 was not found")
}

if field1_, ok = space.FieldsN["name1"]; !ok {
t.Errorf("field name = name1 was not found")
}
if field5_, ok = space.FieldsN["name5"]; !ok {
t.Errorf("field name = name5 was not found")
}
if field1 != field1_ || field5 != field5_ {
t.Errorf("field with id = 1 and field with name 'name1' are different")
}
if field1.Name != "name1" {
t.Errorf("field 1 has incorrect Name")
}
if field1.Type != "" {
t.Errorf("field 1 has incorrect Type")
}
if field2.Name != "" {
t.Errorf("field 2 has incorrect Name")
}
if field2.Type != "type2" {
t.Errorf("field 2 has incorrect Type")
}

if space.Indexes == nil {
t.Errorf("space.Indexes is nill")
}
if space.IndexesN == nil {
t.Errorf("space.IndexesN is nill")
}
if len(space.Indexes) != 2 {
t.Errorf("space.Indexes len is incorrect")
}
if len(space.IndexesN) != 2 {
t.Errorf("space.IndexesN len is incorrect")
}

var index0, index3, index0_, index3_ *Index
if index0, ok = space.Indexes[0]; !ok {
t.Errorf("index id = 0 was not found")
}
if index3, ok = space.Indexes[3]; !ok {
t.Errorf("index id = 3 was not found")
}
if index0_, ok = space.IndexesN["primary"]; !ok {
t.Errorf("index name = primary was not found")
}
if index3_, ok = space.IndexesN["secondary"]; !ok {
t.Errorf("index name = secondary was not found")
}
if index0 != index0_ || index3 != index3_ {
t.Errorf("index with id = 3 and index with name 'secondary' are different")
}
if index3.Id != 3 {
t.Errorf("index has incorrect Id")
}
if index0.Name != "primary" {
t.Errorf("index has incorrect Name")
}
if index0.Type != "hash" || index3.Type != "tree" {
t.Errorf("index has incorrect Type")
}
if !index0.Unique || index3.Unique {
t.Errorf("index has incorrect Unique")
}
if index3.Fields == nil {
t.Errorf("index.Fields is nil")
}
if len(index3.Fields) != 2 {
t.Errorf("index.Fields len is incorrect")
}

ifield1 := index3.Fields[0]
ifield2 := index3.Fields[1]
if ifield1 == nil || ifield2 == nil {
t.Errorf("index field is nil")
}
if ifield1.Id != 1 || ifield2.Id != 2 {
t.Errorf("index field has incorrect Id")
}
if ifield1.Type != "num" || ifield2.Type != "STR" {
t.Errorf("index field has incorrect Type[")
}
}

0 comments on commit b516184

Please sign in to comment.