@@ -91,6 +91,26 @@ func fillExecute(enc *msgpack.Encoder, expr string, args interface{}) error {
91
91
return encodeSQLBind (enc , args )
92
92
}
93
93
94
+ func fillPrepare (enc * msgpack.Encoder , expr string ) error {
95
+ enc .EncodeMapLen (1 )
96
+ enc .EncodeUint64 (KeySQLText )
97
+ return enc .EncodeString (expr )
98
+ }
99
+
100
+ func fillUnprepare (enc * msgpack.Encoder , stmt PreparedStatement ) error {
101
+ enc .EncodeMapLen (1 )
102
+ enc .EncodeUint64 (KeyStmtID )
103
+ return enc .EncodeUint64 (uint64 (stmt .StatementID ))
104
+ }
105
+
106
+ func fillPreparedExecute (enc * msgpack.Encoder , stmt PreparedStatement , args interface {}) error {
107
+ enc .EncodeMapLen (2 )
108
+ enc .EncodeUint64 (KeyStmtID )
109
+ enc .EncodeUint64 (uint64 (stmt .StatementID ))
110
+ enc .EncodeUint64 (KeySQLBind )
111
+ return encodeSQLBind (enc , args )
112
+ }
113
+
94
114
func fillPing (enc * msgpack.Encoder ) error {
95
115
return enc .EncodeMapLen (0 )
96
116
}
@@ -190,6 +210,16 @@ func (conn *Connection) Execute(expr string, args interface{}) (resp *Response,
190
210
return conn .ExecuteAsync (expr , args ).Get ()
191
211
}
192
212
213
+ // Prepare sends a sql statement to prepare.
214
+ //
215
+ // It is equal to conn.PrepareAsync(expr).Get().
216
+ // Since 1.7.0
217
+ func (conn * Connection ) Prepare (expr string ) (stmt * PreparedStatement , err error ) {
218
+ stmt = conn .PrepareAsync (expr )
219
+ err = stmt .wait ()
220
+ return stmt , err
221
+ }
222
+
193
223
// single used for conn.GetTyped for decode one tuple.
194
224
type single struct {
195
225
res interface {}
@@ -389,6 +419,78 @@ func (conn *Connection) ExecuteAsync(expr string, args interface{}) *Future {
389
419
return conn .DoAsync (req )
390
420
}
391
421
422
+ // PrepareAsync sends a sql statement to prepare and returns PreparedStatement object.
423
+ //
424
+ // Since 1.7.0
425
+ func (conn * Connection ) PrepareAsync (expr string ) * PreparedStatement {
426
+ req := newPrepareRequest (expr )
427
+ fut := conn .DoAsync (req )
428
+ stmt := newPreparedStatement (fut , conn )
429
+ return stmt
430
+ }
431
+
432
+ type PreparedStatementID uint64
433
+
434
+ // PreparedStatement is a type for handling prepared statements
435
+ //
436
+ // Since 1.7.0
437
+ type PreparedStatement struct {
438
+ StatementID PreparedStatementID
439
+ MetaData []ColumnMetaData
440
+ ParamCount uint64
441
+ conn * Connection
442
+ fut * Future
443
+ }
444
+
445
+ func newPreparedStatement (fut * Future , conn * Connection ) * PreparedStatement {
446
+ stmt := new (PreparedStatement )
447
+ stmt .fut = fut
448
+ stmt .conn = conn
449
+ return stmt
450
+ }
451
+
452
+ // wait until the prepared statement is ready and fill the statement object
453
+ func (stmt * PreparedStatement ) wait () error {
454
+ resp , err := stmt .fut .Get ()
455
+ stmt .StatementID = PreparedStatementID (resp .StmtID )
456
+ stmt .MetaData = resp .MetaData
457
+ stmt .ParamCount = resp .BindCount
458
+ return err
459
+ }
460
+
461
+ // UnprepareAsync sends an undo request and returns Future
462
+ func (stmt * PreparedStatement ) UnprepareAsync () * Future {
463
+ err := stmt .wait ()
464
+ if err != nil {
465
+ return NewErrorFuture (err )
466
+ }
467
+ req := newUnprepareRequest (* stmt )
468
+ fut := stmt .conn .DoAsync (req )
469
+ return fut
470
+ }
471
+
472
+ // Unprepare undo the prepared statement
473
+ func (stmt * PreparedStatement ) Unprepare () (resp * Response , err error ) {
474
+ return stmt .UnprepareAsync ().Get ()
475
+ }
476
+
477
+ // ExecuteAsync sends the prepared SQL statement for execution and returns Future
478
+ func (stmt * PreparedStatement ) ExecuteAsync (args interface {}) * Future {
479
+ err := stmt .wait ()
480
+ if err != nil {
481
+ return NewErrorFuture (err )
482
+ }
483
+ req := newPreparedExecuteRequest (* stmt )
484
+ req .Args (args )
485
+ fut := stmt .conn .DoAsync (req )
486
+ return fut
487
+ }
488
+
489
+ // Execute sends the prepared SQL statement for execution
490
+ func (stmt * PreparedStatement ) Execute (args interface {}) (resp * Response , err error ) {
491
+ return stmt .ExecuteAsync (args ).Get ()
492
+ }
493
+
392
494
// KeyValueBind is a type for encoding named SQL parameters
393
495
type KeyValueBind struct {
394
496
Key string
@@ -981,3 +1083,63 @@ func (req *ExecuteRequest) Args(args interface{}) *ExecuteRequest {
981
1083
func (req * ExecuteRequest ) Body (res SchemaResolver , enc * msgpack.Encoder ) error {
982
1084
return fillExecute (enc , req .expr , req .args )
983
1085
}
1086
+
1087
+ type prepareRequest struct {
1088
+ baseRequest
1089
+ expr string
1090
+ }
1091
+
1092
+ // newPrepareRequest returns a new empty prepareRequest.
1093
+ func newPrepareRequest (expr string ) * prepareRequest {
1094
+ req := new (prepareRequest )
1095
+ req .requestCode = PrepareRequestCode
1096
+ req .expr = expr
1097
+ return req
1098
+ }
1099
+
1100
+ // Body fills an encoder with the execute request body.
1101
+ func (req * prepareRequest ) Body (res SchemaResolver , enc * msgpack.Encoder ) error {
1102
+ return fillPrepare (enc , req .expr )
1103
+ }
1104
+
1105
+ type unprepareRequest struct {
1106
+ baseRequest
1107
+ stmt PreparedStatement
1108
+ }
1109
+
1110
+ // newUnprepareRequest returns a new empty unprepareRequest.
1111
+ func newUnprepareRequest (stmt PreparedStatement ) * unprepareRequest {
1112
+ req := new (unprepareRequest )
1113
+ req .requestCode = PrepareRequestCode
1114
+ req .stmt = stmt
1115
+ return req
1116
+ }
1117
+
1118
+ // Body fills an encoder with the execute request body.
1119
+ func (req * unprepareRequest ) Body (res SchemaResolver , enc * msgpack.Encoder ) error {
1120
+ return fillUnprepare (enc , req .stmt )
1121
+ }
1122
+
1123
+ type preparedExecuteRequest struct {
1124
+ baseRequest
1125
+ stmt PreparedStatement
1126
+ args interface {}
1127
+ }
1128
+
1129
+ // newPreparedExecuteRequest returns a new empty preparedExecuteRequest.
1130
+ func newPreparedExecuteRequest (stmt PreparedStatement ) * preparedExecuteRequest {
1131
+ req := new (preparedExecuteRequest )
1132
+ req .requestCode = ExecuteRequestCode
1133
+ req .stmt = stmt
1134
+ return req
1135
+ }
1136
+
1137
+ func (req * preparedExecuteRequest ) Args (args interface {}) * preparedExecuteRequest {
1138
+ req .args = args
1139
+ return req
1140
+ }
1141
+
1142
+ // Body fills an encoder with the execute request body.
1143
+ func (req * preparedExecuteRequest ) Body (res SchemaResolver , enc * msgpack.Encoder ) error {
1144
+ return fillPreparedExecute (enc , req .stmt , req .args )
1145
+ }
0 commit comments