Skip to content

Commit 7976cb5

Browse files
authored
Merge pull request #357 from ydb-platform/xsql
* Added simple transaction control constructors `table.OnlineReadOnly…
2 parents c446b8f + af55afd commit 7976cb5

File tree

9 files changed

+133
-113
lines changed

9 files changed

+133
-113
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
* Added simple transaction control constructors `table.OnlineReadOnlyTxControl()` and `table.StaleReadOnlyTxControl()`
2+
* Added transaction control specifier with context `ydb.WithTxControl`
3+
* Added value constructors `types.BytesValue`, `types.BytesValueFromString`, `types.TextValue`
4+
* Removed auto-prepending declare section on `xsql` queries
5+
* Supports `time.Time` as type destination in `xsql` queries
16
* Defined default dial timeout (5 seconds)
27

38
## v3.35.1

internal/xsql/conn.go

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
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

5254
type 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

7070
var (
@@ -107,8 +107,61 @@ func (c *conn) isClosed() bool {
107107

108108
func (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

114167
func (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

324380
func Unwrap(db *sql.DB) (connector *Connector, err error) {

internal/xsql/rows.go

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"database/sql"
66
"database/sql/driver"
7-
"fmt"
87
"io"
98
"sync"
109

@@ -87,19 +86,6 @@ func (r *rows) Close() error {
8786
return r.result.Close()
8887
}
8988

90-
type valuer struct {
91-
v interface{}
92-
}
93-
94-
func (p *valuer) UnmarshalYDB(raw types.RawValue) error {
95-
p.v = raw.Any()
96-
return nil
97-
}
98-
99-
func (p *valuer) Value() interface{} {
100-
return p.v
101-
}
102-
10389
type single struct {
10490
values []sql.NamedArg
10591
}
@@ -125,66 +111,3 @@ func (r *single) Next(dst []driver.Value) error {
125111
r.values = nil
126112
return nil
127113
}
128-
129-
type nopResult struct{}
130-
131-
func (r nopResult) LastInsertId() (int64, error) {
132-
return 0, ErrUnsupported
133-
}
134-
135-
func (r nopResult) RowsAffected() (int64, error) {
136-
return 0, ErrUnsupported
137-
}
138-
139-
type namedValueChecker struct{}
140-
141-
func (namedValueChecker) CheckNamedValue(v *driver.NamedValue) (err error) {
142-
if v.Name == "" {
143-
return fmt.Errorf("ydb: only named parameters are supported")
144-
}
145-
146-
if valuer, ok := v.Value.(driver.Valuer); ok {
147-
v.Value, err = valuer.Value()
148-
if err != nil {
149-
return fmt.Errorf("ydb: driver.Valuer error: %w", err)
150-
}
151-
}
152-
153-
switch x := v.Value.(type) {
154-
case types.Value:
155-
// OK.
156-
case bool:
157-
v.Value = types.BoolValue(x)
158-
case int8:
159-
v.Value = types.Int8Value(x)
160-
case uint8:
161-
v.Value = types.Uint8Value(x)
162-
case int16:
163-
v.Value = types.Int16Value(x)
164-
case uint16:
165-
v.Value = types.Uint16Value(x)
166-
case int32:
167-
v.Value = types.Int32Value(x)
168-
case uint32:
169-
v.Value = types.Uint32Value(x)
170-
case int64:
171-
v.Value = types.Int64Value(x)
172-
case uint64:
173-
v.Value = types.Uint64Value(x)
174-
case float32:
175-
v.Value = types.FloatValue(x)
176-
case float64:
177-
v.Value = types.DoubleValue(x)
178-
case []byte:
179-
v.Value = types.StringValue(x)
180-
case string:
181-
v.Value = types.UTF8Value(x)
182-
case [16]byte:
183-
v.Value = types.UUIDValue(x)
184-
185-
default:
186-
return xerrors.WithStackTrace(fmt.Errorf("ydb: unsupported type: %T", x))
187-
}
188-
189-
return nil
190-
}

internal/xsql/tx.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func (tx *tx) Commit() (err error) {
3737
return errClosedConn
3838
}
3939
defer func() {
40-
tx.conn.tx = nil
40+
tx.conn.currentTx = nil
4141
}()
4242
_, err = tx.tx.CommitTx(tx.ctx)
4343
if err != nil {
@@ -55,9 +55,9 @@ func (tx *tx) Rollback() (err error) {
5555
return errClosedConn
5656
}
5757
defer func() {
58-
tx.conn.tx = nil
58+
tx.conn.currentTx = nil
5959
}()
60-
if tx.conn.tx == nil {
60+
if tx.conn.currentTx == nil {
6161
return nil
6262
}
6363
err = tx.tx.Rollback(tx.ctx)
@@ -72,11 +72,10 @@ func (tx *tx) QueryContext(ctx context.Context, query string, args []driver.Name
7272
defer func() {
7373
onDone(err)
7474
}()
75-
params := toQueryParams(args)
7675
var res result.Result
7776
res, err = tx.tx.Execute(ctx,
78-
queryWithDeclares(query, params),
79-
params,
77+
query,
78+
toQueryParams(args),
8079
dataQueryOptions(ctx)...,
8180
)
8281
if err != nil {
@@ -86,6 +85,7 @@ func (tx *tx) QueryContext(ctx context.Context, query string, args []driver.Name
8685
return nil, tx.conn.checkClosed(xerrors.WithStackTrace(err))
8786
}
8887
return &rows{
88+
conn: tx.conn,
8989
result: res,
9090
}, nil
9191
}
@@ -95,14 +95,13 @@ func (tx *tx) ExecContext(ctx context.Context, query string, args []driver.Named
9595
defer func() {
9696
onDone(err)
9797
}()
98-
params := toQueryParams(args)
9998
_, err = tx.tx.Execute(ctx,
100-
queryWithDeclares(query, params),
101-
params,
99+
query,
100+
toQueryParams(args),
102101
dataQueryOptions(ctx)...,
103102
)
104103
if err != nil {
105104
return nil, tx.conn.checkClosed(xerrors.WithStackTrace(err))
106105
}
107-
return nopResult{}, nil
106+
return driver.ResultNoRows, nil
108107
}

internal/xsql/valuer.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package xsql
2+
3+
import "github.com/ydb-platform/ydb-go-sdk/v3/table/types"
4+
5+
type valuer struct {
6+
v interface{}
7+
}
8+
9+
func (p *valuer) UnmarshalYDB(raw types.RawValue) error {
10+
p.v = raw.Any()
11+
return nil
12+
}
13+
14+
func (p *valuer) Value() interface{} {
15+
return p.v
16+
}

0 commit comments

Comments
 (0)