Skip to content

Commit decf79b

Browse files
committed
sql: adding minimal sql support
That patch adds the support of SQL in connector. Fixes #62
1 parent bec9f72 commit decf79b

File tree

7 files changed

+123
-15
lines changed

7 files changed

+123
-15
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,24 @@ func main() {
282282
log.Println("Error", err)
283283
log.Println("Code", resp.Code)
284284
log.Println("Data", resp.Data)
285+
286+
// prepare map for sql bind
287+
sqlBind := map[string]interface{}{
288+
"id": 1,
289+
"name": "test",
290+
}
291+
// insert data using sql query
292+
resp, err = client.Execute("INSERT INTO SQL_TEST VALUES (:id, :name);", sqlBind)
293+
log.Println("Execute Error", err)
294+
log.Println("Execute Code", resp.Code)
295+
log.Println("Execute Data", resp.Data)
296+
297+
sqlBind = map[string]interface{}{"name": "test"}
298+
// select data using sql query
299+
resp, err = client.Execute("SELECT id, name FROM SQL_TEST WHERE name=:name", sqlBind)
300+
log.Println("Execute Error", err)
301+
log.Println("Execute Code", resp.Code)
302+
log.Println("Execute Data", resp.Data)
285303
}
286304
```
287305

config.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ box.once("init", function()
4040
})
4141
st:truncate()
4242

43+
local st = box.schema.space.create('SQL_TEST', {
44+
id = 515,
45+
temporary = true,
46+
if_not_exists = true,
47+
field_count = 2,
48+
format = {
49+
{name = "ID", type = "unsigned"},
50+
{name = "NAME", type = "string"},
51+
},
52+
})
53+
st:create_index('primary', {
54+
type = 'tree',
55+
parts = {1, 'uint'},
56+
unique = true,
57+
if_not_exists = true,
58+
})
4359
--box.schema.user.grant('guest', 'read,write,execute', 'universe')
4460
box.schema.func.create('box.info')
4561
box.schema.func.create('simple_incr')
@@ -49,6 +65,7 @@ box.once("init", function()
4965
box.schema.user.grant('test', 'execute', 'universe')
5066
box.schema.user.grant('test', 'read,write', 'space', 'test')
5167
box.schema.user.grant('test', 'read,write', 'space', 'schematest')
68+
box.schema.user.grant('test', 'read,write', 'space', 'SQL_TEST')
5269
end)
5370

5471
local function simple_incr(a)

connector.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Connector interface {
1717
Call(functionName string, args interface{}) (resp *Response, err error)
1818
Call17(functionName string, args interface{}) (resp *Response, err error)
1919
Eval(expr string, args interface{}) (resp *Response, err error)
20+
Execute(expr string, args interface{}) (resp *Response, err error)
2021

2122
GetTyped(space, index interface{}, key interface{}, result interface{}) (err error)
2223
SelectTyped(space, index interface{}, offset, limit, iterator uint32, key interface{}, result interface{}) (err error)

const.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,31 @@ const (
1111
EvalRequest = 8
1212
UpsertRequest = 9
1313
Call17Request = 10
14+
ExecuteRequest = 11
1415
PingRequest = 64
1516
SubscribeRequest = 66
1617

17-
KeyCode = 0x00
18-
KeySync = 0x01
19-
KeySpaceNo = 0x10
20-
KeyIndexNo = 0x11
21-
KeyLimit = 0x12
22-
KeyOffset = 0x13
23-
KeyIterator = 0x14
24-
KeyKey = 0x20
25-
KeyTuple = 0x21
26-
KeyFunctionName = 0x22
27-
KeyUserName = 0x23
28-
KeyExpression = 0x27
29-
KeyDefTuple = 0x28
30-
KeyData = 0x30
31-
KeyError = 0x31
18+
KeyCode = 0x00
19+
KeySync = 0x01
20+
KeySpaceNo = 0x10
21+
KeyIndexNo = 0x11
22+
KeyLimit = 0x12
23+
KeyOffset = 0x13
24+
KeyIterator = 0x14
25+
KeyKey = 0x20
26+
KeyTuple = 0x21
27+
KeyFunctionName = 0x22
28+
KeyUserName = 0x23
29+
KeyExpression = 0x27
30+
KeyDefTuple = 0x28
31+
KeyData = 0x30
32+
KeyError = 0x31
33+
KeyMetaData = 0x32
34+
KeySQLText = 0x40
35+
KeySQLBind = 0x41
36+
KeySQLInfo = 0x42
37+
KeySQLInfoRowCount = 0x00
38+
KeySQLInfoAutoIncrementIDS = 0x01
3239

3340
// https://github.com/fl00r/go-tarantool-1.6/issues/2
3441

example_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,24 @@ func Example() {
168168
fmt.Println("Eval Code", resp.Code)
169169
fmt.Println("Eval Data", resp.Data)
170170

171+
// prepare map for sql bind
172+
sqlBind := map[string]interface{}{
173+
"id": 1,
174+
"name": "test",
175+
}
176+
// insert data using sql query
177+
resp, err = client.Execute("INSERT INTO SQL_TEST VALUES (:id, :name);", sqlBind)
178+
fmt.Println("Execute Error", err)
179+
fmt.Println("Execute Code", resp.Code)
180+
fmt.Println("Execute Data", resp.Data)
181+
182+
sqlBind = map[string]interface{}{"name": "test"}
183+
// select data using sql query
184+
resp, err = client.Execute("SELECT id, name FROM SQL_TEST WHERE name=:name", sqlBind)
185+
fmt.Println("Execute Error", err)
186+
fmt.Println("Execute Code", resp.Code)
187+
fmt.Println("Execute Data", resp.Data)
188+
171189
resp, err = client.Replace("test", &Tuple{Id: 11, Msg: "test", Name: "eleven"})
172190
resp, err = client.Replace("test", &Tuple{Id: 12, Msg: "test", Name: "twelve"})
173191

@@ -215,6 +233,12 @@ func Example() {
215233
// Eval Error <nil>
216234
// Eval Code 0
217235
// Eval Data [3]
236+
// Execute Error <nil>
237+
// Execute Code 0
238+
// Execute Data []
239+
// Execute Error <nil>
240+
// Execute Code 0
241+
// Execute Data [[1 test]]
218242
// Fut 0 Error <nil>
219243
// Fut 0 Data [{{} 12 test twelve} {{} 11 test eleven}]
220244
// Fut 1 Error <nil>

multi/multi.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ func (connMulti *ConnectionMulti) Eval(expr string, args interface{}) (resp *tar
294294
return connMulti.getCurrentConnection().Eval(expr, args)
295295
}
296296

297+
func (connMulti *ConnectionMulti) Execute(expr string, args interface{}) (resp *tarantool.Response, err error) {
298+
return connMulti.getCurrentConnection().Execute(expr, args)
299+
}
300+
297301
func (connMulti *ConnectionMulti) GetTyped(space, index interface{}, key interface{}, result interface{}) (err error) {
298302
return connMulti.getCurrentConnection().GetTyped(space, index, key, result)
299303
}

request.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package tarantool
22

33
import (
44
"errors"
5+
"reflect"
56
"time"
67

78
"gopkg.in/vmihailenco/msgpack.v2"
@@ -120,6 +121,13 @@ func (conn *Connection) Eval(expr string, args interface{}) (resp *Response, err
120121
return conn.EvalAsync(expr, args).Get()
121122
}
122123

124+
// Execute passes sql expression for execution.
125+
//
126+
// It is equal to conn.ExecuteAsync(space, tuple).Get().
127+
func (conn *Connection) Execute(expr string, args interface{}) (resp *Response, err error) {
128+
return conn.ExecuteAsync(expr, args).Get()
129+
}
130+
123131
// single used for conn.GetTyped for decode one tuple
124132
type single struct {
125133
res interface{}
@@ -346,10 +354,39 @@ func (conn *Connection) EvalAsync(expr string, args interface{}) *Future {
346354
})
347355
}
348356

357+
// ExecuteAsync sends a sql expression for execution and returns Future.
358+
func (conn *Connection) ExecuteAsync(expr string, args interface{}) *Future {
359+
future := conn.newFuture(ExecuteRequest)
360+
bind := makeSQLBind(args)
361+
return future.send(conn, func(enc *msgpack.Encoder) error {
362+
enc.EncodeMapLen(2)
363+
enc.EncodeUint64(KeySQLText)
364+
enc.EncodeString(expr)
365+
enc.EncodeUint64(KeySQLBind)
366+
return enc.Encode(bind)
367+
})
368+
}
369+
349370
//
350371
// private
351372
//
352373

374+
func makeSQLBind(from interface{}) interface{} {
375+
val := reflect.ValueOf(from)
376+
arr := []map[string]interface{}{}
377+
378+
if val.Kind() == reflect.Map {
379+
for _, e := range val.MapKeys() {
380+
mp := map[string]interface{}{}
381+
v := val.MapIndex(e)
382+
t := v.Interface()
383+
mp[":"+e.String()] = t
384+
arr = append(arr, mp)
385+
}
386+
}
387+
return arr
388+
}
389+
353390
func (fut *Future) pack(h *smallWBuf, enc *msgpack.Encoder, body func(*msgpack.Encoder) error) (err error) {
354391
rid := fut.requestId
355392
hl := h.Len()

0 commit comments

Comments
 (0)