66 "database/sql/driver"
77 "fmt"
88 "sync/atomic"
9+ "time"
910
1011 "github.com/ydb-platform/ydb-go-sdk/v3/internal/retry"
1112 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
@@ -14,6 +15,7 @@ import (
1415 "github.com/ydb-platform/ydb-go-sdk/v3/table"
1516 "github.com/ydb-platform/ydb-go-sdk/v3/table/options"
1617 "github.com/ydb-platform/ydb-go-sdk/v3/table/result"
18+ "github.com/ydb-platform/ydb-go-sdk/v3/table/types"
1719 "github.com/ydb-platform/ydb-go-sdk/v3/trace"
1820)
1921
@@ -50,21 +52,19 @@ func withTrace(t trace.DatabaseSQL) connOption {
5052}
5153
5254type conn struct {
53- namedValueChecker
54-
5555 connector * Connector
56+ trace trace.DatabaseSQL
5657 session table.ClosableSession // Immutable and r/o usage.
57- closed uint32
5858
59+ closed uint32
5960 defaultQueryMode QueryMode
61+
6062 defaultTxControl * table.TransactionControl
63+ dataOpts []options.ExecuteDataQueryOption
6164
62- dataOpts []options.ExecuteDataQueryOption
6365 scanOpts []options.ExecuteScanQueryOption
6466
65- tx * tx
66-
67- trace trace.DatabaseSQL
67+ currentTx * tx
6868}
6969
7070var (
@@ -107,8 +107,61 @@ func (c *conn) isClosed() bool {
107107
108108func (c * conn ) setClosed () {
109109 if atomic .CompareAndSwapUint32 (& c .closed , 0 , 1 ) {
110- c .Close ()
110+ _ = c .Close ()
111+ }
112+ }
113+
114+ func (conn ) CheckNamedValue (v * driver.NamedValue ) (err error ) {
115+ if v .Name == "" {
116+ return fmt .Errorf ("ydb: only named parameters are supported" )
117+ }
118+
119+ if valuer , ok := v .Value .(driver.Valuer ); ok {
120+ v .Value , err = valuer .Value ()
121+ if err != nil {
122+ return fmt .Errorf ("ydb: driver.Valuer error: %w" , err )
123+ }
124+ }
125+
126+ switch x := v .Value .(type ) {
127+ case types.Value :
128+ // OK.
129+ case bool :
130+ v .Value = types .BoolValue (x )
131+ case int8 :
132+ v .Value = types .Int8Value (x )
133+ case uint8 :
134+ v .Value = types .Uint8Value (x )
135+ case int16 :
136+ v .Value = types .Int16Value (x )
137+ case uint16 :
138+ v .Value = types .Uint16Value (x )
139+ case int32 :
140+ v .Value = types .Int32Value (x )
141+ case uint32 :
142+ v .Value = types .Uint32Value (x )
143+ case int64 :
144+ v .Value = types .Int64Value (x )
145+ case uint64 :
146+ v .Value = types .Uint64Value (x )
147+ case float32 :
148+ v .Value = types .FloatValue (x )
149+ case float64 :
150+ v .Value = types .DoubleValue (x )
151+ case []byte :
152+ v .Value = types .StringValue (x )
153+ case string :
154+ v .Value = types .UTF8Value (x )
155+ case [16 ]byte :
156+ v .Value = types .UUIDValue (x )
157+ case time.Time :
158+ v .Value = types .DateValueFromTime (x )
159+
160+ default :
161+ return xerrors .WithStackTrace (fmt .Errorf ("ydb: unsupported type: %T" , x ))
111162 }
163+
164+ return nil
112165}
113166
114167func (c * conn ) PrepareContext (ctx context.Context , query string ) (_ driver.Stmt , err error ) {
@@ -135,13 +188,13 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
135188 if c .isClosed () {
136189 return nil , errClosedConn
137190 }
138- if c .tx != nil {
191+ if c .currentTx != nil {
139192 if m != DataQueryMode {
140193 return nil , xerrors .WithStackTrace (
141- fmt .Errorf ("query mode `%s` not supported with tx " , m .String ()),
194+ fmt .Errorf ("query mode `%s` not supported with currentTx " , m .String ()),
142195 )
143196 }
144- return c .tx .ExecContext (ctx , query , args )
197+ return c .currentTx .ExecContext (ctx , query , args )
145198 }
146199 switch m {
147200 case DataQueryMode :
@@ -158,19 +211,19 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
158211 if err = res .Err (); err != nil {
159212 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
160213 }
161- return nopResult {} , nil
214+ return driver . ResultNoRows , nil
162215 case SchemeQueryMode :
163216 err = c .session .ExecuteSchemeQuery (ctx , query )
164217 if err != nil {
165218 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
166219 }
167- return nopResult {} , nil
220+ return driver . ResultNoRows , nil
168221 case ScriptingQueryMode :
169222 _ , err = c .connector .connection .Scripting ().StreamExecute (ctx , query , toQueryParams (args ))
170223 if err != nil {
171224 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
172225 }
173- return nopResult {} , nil
226+ return driver . ResultNoRows , nil
174227 default :
175228 return nil , fmt .Errorf ("unsupported query mode '%s' for execute query" , m )
176229 }
@@ -185,13 +238,13 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
185238 if c .isClosed () {
186239 return nil , errClosedConn
187240 }
188- if c .tx != nil {
241+ if c .currentTx != nil {
189242 if m != DataQueryMode {
190243 return nil , xerrors .WithStackTrace (
191- fmt .Errorf ("query mode `%s` not supported with tx " , m .String ()),
244+ fmt .Errorf ("query mode `%s` not supported with currentTx " , m .String ()),
192245 )
193246 }
194- return c .tx .QueryContext (ctx , query , args )
247+ return c .currentTx .QueryContext (ctx , query , args )
195248 }
196249 switch m {
197250 case DataQueryMode :
@@ -209,6 +262,7 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
209262 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
210263 }
211264 return & rows {
265+ conn : c ,
212266 result : res ,
213267 }, nil
214268 case ScanQueryMode :
@@ -225,6 +279,7 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
225279 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
226280 }
227281 return & rows {
282+ conn : c ,
228283 result : res ,
229284 }, nil
230285 case ExplainQueryMode :
@@ -249,6 +304,7 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
249304 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
250305 }
251306 return & rows {
307+ conn : c ,
252308 result : res ,
253309 }, nil
254310 default :
@@ -299,9 +355,9 @@ func (c *conn) BeginTx(ctx context.Context, txOptions driver.TxOptions) (_ drive
299355 if c .isClosed () {
300356 return nil , errClosedConn
301357 }
302- if c .tx != nil {
358+ if c .currentTx != nil {
303359 return nil , xerrors .WithStackTrace (
304- fmt .Errorf ("conn already have an opened tx : %s" , c .tx .ID ()),
360+ fmt .Errorf ("conn already have an opened currentTx : %s" , c .currentTx .ID ()),
305361 )
306362 }
307363 var txc table.TxOption
@@ -313,12 +369,12 @@ func (c *conn) BeginTx(ctx context.Context, txOptions driver.TxOptions) (_ drive
313369 if err != nil {
314370 return nil , c .checkClosed (xerrors .WithStackTrace (err ))
315371 }
316- c .tx = & tx {
372+ c .currentTx = & tx {
317373 conn : c ,
318374 ctx : ctx ,
319375 tx : transaction ,
320376 }
321- return c .tx , nil
377+ return c .currentTx , nil
322378}
323379
324380func Unwrap (db * sql.DB ) (connector * Connector , err error ) {
0 commit comments