Skip to content

Commit 5a117ab

Browse files
committed
[TO SQUASH IF OK]
1 parent f42b5a8 commit 5a117ab

File tree

7 files changed

+136
-117
lines changed

7 files changed

+136
-117
lines changed

connector.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ 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 interface{}, args interface{}) (resp *Response, err error)
21-
Prepare(expr string) (resp *Response, err error)
22-
Unprepare(stmt uint64) (resp *Response, err error)
20+
Execute(expr string, args interface{}) (resp *Response, err error)
21+
Prepare(expr string) (stmt *PreparedStatement, err error)
2322

2423
GetTyped(space, index interface{}, key interface{}, result interface{}) (err error)
2524
SelectTyped(space, index interface{}, offset, limit, iterator uint32, key interface{}, result interface{}) (err error)
@@ -30,7 +29,7 @@ type Connector interface {
3029
CallTyped(functionName string, args interface{}, result interface{}) (err error)
3130
Call17Typed(functionName string, args interface{}, result interface{}) (err error)
3231
EvalTyped(expr string, args interface{}, result interface{}) (err error)
33-
ExecuteTyped(expr interface{}, args interface{}, result interface{}) (SQLInfo, []ColumnMetaData, error)
32+
ExecuteTyped(expr string, args interface{}, result interface{}) (SQLInfo, []ColumnMetaData, error)
3433

3534
SelectAsync(space, index interface{}, offset, limit, iterator uint32, key interface{}) *Future
3635
InsertAsync(space interface{}, tuple interface{}) *Future
@@ -41,7 +40,6 @@ type Connector interface {
4140
CallAsync(functionName string, args interface{}) *Future
4241
Call17Async(functionName string, args interface{}) *Future
4342
EvalAsync(expr string, args interface{}) *Future
44-
ExecuteAsync(expr interface{}, args interface{}) *Future
45-
PrepareAsync(expr string) *Future
46-
UnprepareAsync(stmt uint64) *Future
43+
ExecuteAsync(expr string, args interface{}) *Future
44+
PrepareAsync(expr string) *PreparedStatement
4745
}

const.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const (
3232
KeyData = 0x30
3333
KeyError = 0x31
3434
KeyMetaData = 0x32
35+
KeyBindCount = 0x34
3536
KeySQLText = 0x40
3637
KeySQLBind = 0x41
3738
KeySQLInfo = 0x42

example_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,13 +524,10 @@ func ExampleConnection_Prepare() {
524524
stmtResp, err := client.Prepare("SELECT id FROM SQL_TEST WHERE id=? AND name=?")
525525
fmt.Println("Prepare")
526526
fmt.Println("Error", err)
527-
fmt.Println("Code", stmtResp.Code)
528-
fmt.Println("Statement ID", stmtResp.StmtID)
529-
530-
stmtID := stmtResp.StmtID
527+
fmt.Println("Statement ID", stmtResp.StatementID)
531528

532529
// pass the id of the statement to Execute
533-
resp, err := client.Execute(stmtID, []interface{}{2, "test"})
530+
resp, err := stmtResp.Execute([]interface{}{2, "test"})
534531
fmt.Println("Execute")
535532
fmt.Println("Error", err)
536533
fmt.Println("Code", resp.Code)

multi/multi.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -343,23 +343,17 @@ func (connMulti *ConnectionMulti) Eval(expr string, args interface{}) (resp *tar
343343
// Execute passes a sql expression to Tarantool for execution.
344344
//
345345
// Since 1.6.0
346-
func (connMulti *ConnectionMulti) Execute(expr interface{}, args interface{}) (resp *tarantool.Response, err error) {
346+
func (connMulti *ConnectionMulti) Execute(expr string, args interface{}) (resp *tarantool.Response, err error) {
347347
return connMulti.getCurrentConnection().Execute(expr, args)
348348
}
349349

350350
// Prepare sends a sql statement to prepare.
351351
//
352-
// Since 1.6.0
353-
func (connMulti *ConnectionMulti) Prepare(expr string) (resp *tarantool.Response, err error) {
354-
return connMulti.getCurrentConnection().Prepare(expr)
355-
}
356-
357-
// Unprepare undo the result of Prepare request.
352+
// Returns a PreparedStatement object for the current connection.
358353
//
359-
// It is equal to conn.UnprepareAsync(stmt).Get().
360354
// Since 1.6.0
361-
func (connMulti *ConnectionMulti) Unprepare(stmt uint64) (resp *tarantool.Response, err error) {
362-
return connMulti.getCurrentConnection().Unprepare(stmt)
355+
func (connMulti *ConnectionMulti) Prepare(expr string) (resp *tarantool.PreparedStatement, err error) {
356+
return connMulti.getCurrentConnection().Prepare(expr)
363357
}
364358

365359
// GetTyped performs select (with limit = 1 and offset = 0) to box space and
@@ -417,7 +411,7 @@ func (connMulti *ConnectionMulti) EvalTyped(expr string, args interface{}, resul
417411
}
418412

419413
// ExecuteTyped passes a sql expression for execution.
420-
func (connMulti *ConnectionMulti) ExecuteTyped(expr interface{}, args interface{}, result interface{}) (tarantool.SQLInfo, []tarantool.ColumnMetaData, error) {
414+
func (connMulti *ConnectionMulti) ExecuteTyped(expr string, args interface{}, result interface{}) (tarantool.SQLInfo, []tarantool.ColumnMetaData, error) {
421415
return connMulti.getCurrentConnection().ExecuteTyped(expr, args, result)
422416
}
423417

@@ -478,20 +472,13 @@ func (connMulti *ConnectionMulti) EvalAsync(expr string, args interface{}) *tara
478472
// ExecuteAsync passes a sql expression for execution.
479473
//
480474
// Since 1.6.0
481-
func (connMulti *ConnectionMulti) ExecuteAsync(expr interface{}, args interface{}) *tarantool.Future {
475+
func (connMulti *ConnectionMulti) ExecuteAsync(expr string, args interface{}) *tarantool.Future {
482476
return connMulti.getCurrentConnection().ExecuteAsync(expr, args)
483477
}
484478

485479
// PrepareAsync passes a SQL statement to prepare.
486480
//
487481
// Since 1.6.0
488-
func (connMulti *ConnectionMulti) PrepareAsync(expr string) *tarantool.Future {
482+
func (connMulti *ConnectionMulti) PrepareAsync(expr string) *tarantool.PreparedStatement {
489483
return connMulti.getCurrentConnection().PrepareAsync(expr)
490484
}
491-
492-
// UnprepareAsync undo the result of Prepare request and returns Future.
493-
//
494-
// Since 1.6.0
495-
func (connMulti *ConnectionMulti) UnprepareAsync(stmt uint64) *tarantool.Future {
496-
return connMulti.getCurrentConnection().UnprepareAsync(stmt)
497-
}

request.go

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -127,24 +127,18 @@ func (conn *Connection) Eval(expr string, args interface{}) (resp *Response, err
127127
//
128128
// It is equal to conn.ExecuteAsync(expr, args).Get().
129129
// Since 1.6.0
130-
func (conn *Connection) Execute(expr interface{}, args interface{}) (resp *Response, err error) {
130+
func (conn *Connection) Execute(expr string, args interface{}) (resp *Response, err error) {
131131
return conn.ExecuteAsync(expr, args).Get()
132132
}
133133

134134
// Prepare sends a sql statement to prepare.
135135
//
136136
// It is equal to conn.PrepareAsync(expr).Get().
137137
// Since 1.6.0
138-
func (conn *Connection) Prepare(expr string) (resp *Response, err error) {
139-
return conn.PrepareAsync(expr).Get()
140-
}
141-
142-
// Unprepare undo the result of Prepare request.
143-
//
144-
// It is equal to conn.UnprepareAsync(stmt).Get().
145-
// Since 1.6.0
146-
func (conn *Connection) Unprepare(stmt uint64) (resp *Response, err error) {
147-
return conn.UnprepareAsync(stmt).Get()
138+
func (conn *Connection) Prepare(expr string) (stmt *PreparedStatement, err error) {
139+
stmt = conn.PrepareAsync(expr)
140+
err = stmt.wait()
141+
return stmt, err
148142
}
149143

150144
// single used for conn.GetTyped for decode one tuple.
@@ -243,7 +237,7 @@ func (conn *Connection) EvalTyped(expr string, args interface{}, result interfac
243237
//
244238
// In addition to error returns sql info and columns meta data
245239
// Since 1.6.0
246-
func (conn *Connection) ExecuteTyped(expr interface{}, args interface{}, result interface{}) (SQLInfo, []ColumnMetaData, error) {
240+
func (conn *Connection) ExecuteTyped(expr string, args interface{}, result interface{}) (SQLInfo, []ColumnMetaData, error) {
247241
fut := conn.ExecuteAsync(expr, args)
248242
err := fut.GetTyped(&result)
249243
return fut.resp.SQLInfo, fut.resp.MetaData, err
@@ -385,28 +379,12 @@ func (conn *Connection) EvalAsync(expr string, args interface{}) *Future {
385379

386380
// ExecuteAsync sends a sql expression for execution and returns Future.
387381
// Since 1.6.0
388-
func (conn *Connection) ExecuteAsync(expr interface{}, args interface{}) *Future {
382+
func (conn *Connection) ExecuteAsync(expr string, args interface{}) *Future {
389383
future := conn.newFuture(ExecuteRequest)
390-
var stmtID uint64
391-
exprStr, ok := expr.(string)
392-
if !ok {
393-
stmtID, ok = expr.(uint64)
394-
if !ok {
395-
err := errors.New("expr argument must be either string or uint64")
396-
return NewErrorFuture(err)
397-
}
398-
return future.send(conn, func(enc *msgpack.Encoder) error {
399-
enc.EncodeMapLen(2)
400-
enc.EncodeUint64(KeyStmtID)
401-
enc.EncodeUint64(stmtID)
402-
enc.EncodeUint64(KeySQLBind)
403-
return encodeSQLBind(enc, args)
404-
})
405-
}
406384
return future.send(conn, func(enc *msgpack.Encoder) error {
407385
enc.EncodeMapLen(2)
408386
enc.EncodeUint64(KeySQLText)
409-
enc.EncodeString(exprStr)
387+
enc.EncodeString(expr)
410388
enc.EncodeUint64(KeySQLBind)
411389
return encodeSQLBind(enc, args)
412390
})
@@ -415,27 +393,77 @@ func (conn *Connection) ExecuteAsync(expr interface{}, args interface{}) *Future
415393
// PrepareAsync sends a sql statement to prepare and returns Future.
416394
//
417395
// Since 1.6.0
418-
func (conn *Connection) PrepareAsync(expr string) *Future {
396+
func (conn *Connection) PrepareAsync(expr string) *PreparedStatement {
419397
future := conn.newFuture(PrepareRequest)
420-
return future.send(conn, func(enc *msgpack.Encoder) error {
398+
stmt := newPreparedStatement(future.send(conn, func(enc *msgpack.Encoder) error {
421399
enc.EncodeMapLen(1)
422400
enc.EncodeUint64(KeySQLText)
423401
return enc.EncodeString(expr)
424-
})
402+
}), conn)
403+
return stmt
425404
}
426405

427-
// UnprepareAsync undo the result of Prepare request and returns Future.
428-
//
429-
// Since 1.6.0
430-
func (conn *Connection) UnprepareAsync(stmt uint64) *Future {
431-
future := conn.newFuture(PrepareRequest)
432-
return future.send(conn, func(enc *msgpack.Encoder) error {
406+
type PreparedStatementID uint64
407+
408+
type PreparedStatement struct {
409+
StatementID PreparedStatementID
410+
MetaData []ColumnMetaData
411+
ParamCount uint64
412+
conn *Connection
413+
fut *Future
414+
}
415+
416+
func newPreparedStatement(fut *Future, conn *Connection) *PreparedStatement {
417+
stmt := new(PreparedStatement)
418+
stmt.fut = fut
419+
stmt.conn = conn
420+
return stmt
421+
}
422+
423+
// wait until the prepared statement is ready and fill the statement object
424+
func (stmt *PreparedStatement) wait() error {
425+
resp, err := stmt.fut.Get()
426+
stmt.StatementID = PreparedStatementID(resp.StmtID)
427+
stmt.MetaData = resp.MetaData
428+
stmt.ParamCount = resp.BindCount
429+
return err
430+
}
431+
432+
func (stmt *PreparedStatement) UnprepareAsync() *Future {
433+
err := stmt.wait()
434+
if err != nil {
435+
return NewErrorFuture(err)
436+
}
437+
future := stmt.conn.newFuture(PrepareRequest)
438+
return future.send(stmt.conn, func(enc *msgpack.Encoder) error {
433439
enc.EncodeMapLen(1)
434440
enc.EncodeUint64(KeyStmtID)
435-
return enc.EncodeUint64(stmt)
441+
return enc.EncodeUint64(uint64(stmt.StatementID))
442+
})
443+
}
444+
445+
func (stmt *PreparedStatement) Unprepare() (resp *Response, err error) {
446+
return stmt.UnprepareAsync().Get()
447+
}
448+
449+
func (stmt *PreparedStatement) ExecuteAsync(args interface{}) *Future {
450+
err := stmt.wait()
451+
if err != nil {
452+
return NewErrorFuture(err)
453+
}
454+
return stmt.fut.send(stmt.conn, func(enc *msgpack.Encoder) error {
455+
enc.EncodeMapLen(2)
456+
enc.EncodeUint64(KeyStmtID)
457+
enc.EncodeUint64(uint64(stmt.StatementID))
458+
enc.EncodeUint64(KeySQLBind)
459+
return encodeSQLBind(enc, args)
436460
})
437461
}
438462

463+
func (stmt *PreparedStatement) Execute(args interface{}) (resp *Response, err error) {
464+
return stmt.ExecuteAsync(args).Get()
465+
}
466+
439467
// KeyValueBind is a type for encoding named SQL parameters
440468
type KeyValueBind struct {
441469
Key string

response.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ type Response struct {
1111
Code uint32
1212
Error string // error message
1313
// Data contains deserialized data for untyped requests
14-
Data []interface{}
15-
MetaData []ColumnMetaData
16-
SQLInfo SQLInfo
17-
StmtID uint64
18-
buf smallBuf
14+
Data []interface{}
15+
MetaData []ColumnMetaData
16+
SQLInfo SQLInfo
17+
StmtID uint64
18+
BindCount uint64
19+
buf smallBuf
1920
}
2021

2122
type ColumnMetaData struct {
@@ -183,6 +184,10 @@ func (resp *Response) decodeBody() (err error) {
183184
if resp.StmtID, err = d.DecodeUint64(); err != nil {
184185
return err
185186
}
187+
case KeyBindCount:
188+
if resp.BindCount, err = d.DecodeUint64(); err != nil {
189+
return err
190+
}
186191
default:
187192
if err = d.Skip(); err != nil {
188193
return err

0 commit comments

Comments
 (0)