@@ -127,24 +127,18 @@ func (conn *Connection) Eval(expr string, args interface{}) (resp *Response, err
127
127
//
128
128
// It is equal to conn.ExecuteAsync(expr, args).Get().
129
129
// 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 ) {
131
131
return conn .ExecuteAsync (expr , args ).Get ()
132
132
}
133
133
134
134
// Prepare sends a sql statement to prepare.
135
135
//
136
136
// It is equal to conn.PrepareAsync(expr).Get().
137
137
// 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
148
142
}
149
143
150
144
// single used for conn.GetTyped for decode one tuple.
@@ -243,7 +237,7 @@ func (conn *Connection) EvalTyped(expr string, args interface{}, result interfac
243
237
//
244
238
// In addition to error returns sql info and columns meta data
245
239
// 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 ) {
247
241
fut := conn .ExecuteAsync (expr , args )
248
242
err := fut .GetTyped (& result )
249
243
return fut .resp .SQLInfo , fut .resp .MetaData , err
@@ -385,28 +379,12 @@ func (conn *Connection) EvalAsync(expr string, args interface{}) *Future {
385
379
386
380
// ExecuteAsync sends a sql expression for execution and returns Future.
387
381
// Since 1.6.0
388
- func (conn * Connection ) ExecuteAsync (expr interface {} , args interface {}) * Future {
382
+ func (conn * Connection ) ExecuteAsync (expr string , args interface {}) * Future {
389
383
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
- }
406
384
return future .send (conn , func (enc * msgpack.Encoder ) error {
407
385
enc .EncodeMapLen (2 )
408
386
enc .EncodeUint64 (KeySQLText )
409
- enc .EncodeString (exprStr )
387
+ enc .EncodeString (expr )
410
388
enc .EncodeUint64 (KeySQLBind )
411
389
return encodeSQLBind (enc , args )
412
390
})
@@ -415,27 +393,77 @@ func (conn *Connection) ExecuteAsync(expr interface{}, args interface{}) *Future
415
393
// PrepareAsync sends a sql statement to prepare and returns Future.
416
394
//
417
395
// Since 1.6.0
418
- func (conn * Connection ) PrepareAsync (expr string ) * Future {
396
+ func (conn * Connection ) PrepareAsync (expr string ) * PreparedStatement {
419
397
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 {
421
399
enc .EncodeMapLen (1 )
422
400
enc .EncodeUint64 (KeySQLText )
423
401
return enc .EncodeString (expr )
424
- })
402
+ }), conn )
403
+ return stmt
425
404
}
426
405
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 {
433
439
enc .EncodeMapLen (1 )
434
440
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 )
436
460
})
437
461
}
438
462
463
+ func (stmt * PreparedStatement ) Execute (args interface {}) (resp * Response , err error ) {
464
+ return stmt .ExecuteAsync (args ).Get ()
465
+ }
466
+
439
467
// KeyValueBind is a type for encoding named SQL parameters
440
468
type KeyValueBind struct {
441
469
Key string
0 commit comments