ydbsql

package
v2.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2021 License: Apache-2.0 Imports: 13 Imported by: 0

README

[Experimental] Go database/sql driver for YDB This is an experimental version of Go database/sql driver for YDB. It is in active development and is not intended for use in production environments.

Documentation

Overview

Package ydbsql provides integration of YDB table API with database/sql driver interface.

The recommended usage of this package is as follows:

import "ydb/ydbsql"

func main() {
	db, err := sql.OpenDB(ydbsql.Connector(
		// Note that you could pass already configured instance of
		// ydb/table.Client here. This may be useful when tracing setup
		// must be prepared directly on Client structure.
		//
		// There are few other useful options, see ConnectorOption type for
		// more details.
	))
}

But, as common for sql driver implementations, there is a standard way of database initialization via sql.Open() function:

import _ "ydb/ydbsql" // for "ydb" sql driver registration.
import "database/sql"

func main() {
	db, err := sql.Open("ydb", "ydb://endpoint/database?auth-token=secret")
}

That is, data source name must be a welformed URL, with scheme "ydb", host for YDB endpoint server, and path for database name. Note that token parameter is required.

Data source name parameters:

token – access token to be used during requests (required).

As you may notice, initialization via sql.Open() does not provide ability to setup tracing configuration.

Note that unlike ydb package, ydbsql retrying most ydb errors implicitly. That is, calling db.QueryContext() or db.ExecContext() will retry operation when it receives retriable error from ydb. But it is not possible to provide same logic for transactions. There is a TxDoer struct or DoTx() function (which is just a shortcut) for this purpose:

import "ydb/ydbsql"

func main() {
	db, err := sql.OpenDB(ydbsql.Connector(...))
	if err != nil {
		// handle error
	}

	ctx, cancel := context.WithTimeout(10 * time.Second)
	defer cancel()

	err = db.ExecContext(ctx, ...) // Retries are implicit.
	if err != nil {
		// handle error
	}

	err = db.QueryContext(ctx, ...) // Retries are implicit.
	if err != nil {
		// handle error
	}

	// Explicit retries for transactions.
	err = ydbsql.DoTx(ctx, db, func(ctx context.Context, tx *sql.Tx) error {
		// Execute statements here.
		// Note that Commit()/Rollback() are not neccessary here.
	})
	if err != nil {
		// handle error
	}
}

Note that database/sql package reuses sql.Conn instances which are wrappers around ydb/table.Session instances in case of ydbsql. It could be reasonable to increase the number of reused sessions via database/sql.DB.SetMaxIdleConns() and database/sql.DB.SetMaxOpenConns() calls. If doing so, it is also highly recommended to setup inner session pool's size limit to the same value by passing WithSessionPoolSizeLimit() option to the Connector() function.

It is worth noting that YDB supports server side operation timeout. That is, client could set up operation timeout among other operation options. When this timeout exceeds, YDB will try to cancel operation execution and in any result of the cancelation appropriate timeout error will be returned. By default, this package "mirrors" context.Context deadlines and passes operation timeout option if context deadline is not empty. To configure or disable such behavior please see appropriate Connector options.

Index

Constants

This section is empty.

Variables

View Source
var (
	DefaultIdleThreshold        = 5 * time.Second
	DefaultSessionPoolSizeLimit = 1 << 12
)
View Source
var (
	ErrDeprecated          = errors.New("ydbsql: deprecated")
	ErrUnsupported         = errors.New("ydbsql: not supported")
	ErrActiveTransaction   = errors.New("ydbsql: can not begin tx within active tx")
	ErrNoActiveTransaction = errors.New("ydbsql: no active tx to work with")
	ErrSessionBusy         = errors.New("ydbsql: session is busy")
	ErrResultTruncated     = errors.New("ydbsql: result set has been truncated")
)

Functions

func Connector

func Connector(opts ...ConnectorOption) driver.Connector

func ContextScanQueryMode

func ContextScanQueryMode(ctx context.Context) bool

ContextScanQueryMode returns true if context contains scan query flag.

func DoTx

func DoTx(ctx context.Context, db *sql.DB, f TxOperationFunc) error

DoTx is a shortcut for calling Do(ctx, f) on initialized TxDoer with DB field set to given db.

func Nullable

func Nullable(s sql.Scanner) sql.Scanner

func WithScanQuery

func WithScanQuery(ctx context.Context) context.Context

WithScanQuery returns a copy of parent context with scan query flag.

func WithTrace

func WithTrace(ctx context.Context, t Trace) context.Context

WithTrace returns context which has associated Trace with it.

Types

type ConnectorOption

type ConnectorOption func(*connector)

func WithClient

func WithClient(client *table.Client) ConnectorOption

func WithClientTrace

func WithClientTrace(t table.ClientTrace) ConnectorOption

func WithCredentials

func WithCredentials(creds ydb.Credentials) ConnectorOption

func WithDatabase

func WithDatabase(db string) ConnectorOption

func WithDefaultExecDataQueryOption

func WithDefaultExecDataQueryOption(opts ...table.ExecuteDataQueryOption) ConnectorOption

func WithDefaultExecScanQueryOption

func WithDefaultExecScanQueryOption(opts ...table.ExecuteScanQueryOption) ConnectorOption

func WithDefaultTxControl

func WithDefaultTxControl(txControl *table.TransactionControl) ConnectorOption

func WithDialer

func WithDialer(d ydb.Dialer) ConnectorOption

func WithDriverConfig

func WithDriverConfig(config ydb.DriverConfig) ConnectorOption

func WithDriverTrace

func WithDriverTrace(t ydb.DriverTrace) ConnectorOption

func WithEndpoint

func WithEndpoint(addr string) ConnectorOption

func WithMaxRetries

func WithMaxRetries(n int) ConnectorOption

func WithRetryBackoff

func WithRetryBackoff(b ydb.Backoff) ConnectorOption

func WithSessionPoolBusyCheckInterval

func WithSessionPoolBusyCheckInterval(d time.Duration) ConnectorOption

func WithSessionPoolCreateSessionTimeout

func WithSessionPoolCreateSessionTimeout(d time.Duration) ConnectorOption

func WithSessionPoolDeleteTimeout

func WithSessionPoolDeleteTimeout(d time.Duration) ConnectorOption

func WithSessionPoolIdleThreshold

func WithSessionPoolIdleThreshold(d time.Duration) ConnectorOption

func WithSessionPoolKeepAliveBatchSize

func WithSessionPoolKeepAliveBatchSize(n int) ConnectorOption

func WithSessionPoolKeepAliveTimeout

func WithSessionPoolKeepAliveTimeout(d time.Duration) ConnectorOption

func WithSessionPoolSizeLimit

func WithSessionPoolSizeLimit(n int) ConnectorOption

func WithSessionPoolTrace

func WithSessionPoolTrace(t table.SessionPoolTrace) ConnectorOption

type Date

type Date time.Time

func (*Date) Scan

func (d *Date) Scan(x interface{}) error

func (Date) Value

func (d Date) Value() ydb.Value

type Datetime

type Datetime time.Time

func (*Datetime) Scan

func (d *Datetime) Scan(x interface{}) error

func (Datetime) Value

func (d Datetime) Value() ydb.Value

type Decimal

type Decimal struct {
	Bytes     [16]byte
	Precision uint32
	Scale     uint32
}

func (*Decimal) Scan

func (d *Decimal) Scan(x interface{}) error

type Declaration

type Declaration struct {
	// contains filtered or unexported fields
}

func (*Declaration) Declare

func (d *Declaration) Declare(name string, t ydb.Type)

func (*Declaration) String

func (d *Declaration) String() string

func (*Declaration) WriteTo

func (d *Declaration) WriteTo(dest io.Writer) (int64, error)

type DialDoneInfo

type DialDoneInfo struct {
	Context context.Context
	Error   error
}

type DialStartInfo

type DialStartInfo struct {
	Context context.Context
}

type Driver

type Driver struct {
	// contains filtered or unexported fields
}

Driver is an adapter to allow the use table client as sql.Driver instance. The main purpose of this type is exported is an ability to call Unwrap() method on it to receive raw *table.Client instance.

func (*Driver) Close

func (d *Driver) Close() error

func (*Driver) Open

func (d *Driver) Open(name string) (driver.Conn, error)

Open returns a new connection to the ydb.

func (*Driver) OpenConnector

func (d *Driver) OpenConnector(name string) (driver.Connector, error)

func (*Driver) Unwrap

func (d *Driver) Unwrap(ctx context.Context) (*table.Client, error)

type Interval

type Interval time.Duration

func (*Interval) Scan

func (d *Interval) Scan(x interface{}) error

func (Interval) Value

func (d Interval) Value() ydb.Value

type RetryConfig

type RetryConfig struct {
	// MaxRetries is a number of maximum attempts to retry a failed operation.
	// If MaxRetries is zero then no attempts will be made.
	MaxRetries int

	// RetryChecker contains options of mapping errors to retry mode.
	RetryChecker ydb.RetryChecker

	// Backoff is a selected backoff policy.
	// If backoff is nil, then the DefaultBackoff is used.
	Backoff ydb.Backoff
}

type Timestamp

type Timestamp time.Time

func (*Timestamp) Scan

func (d *Timestamp) Scan(x interface{}) error

func (Timestamp) Value

func (d Timestamp) Value() ydb.Value

type Trace

type Trace struct {
	OnDial func(DialStartInfo) func(DialDoneInfo)
}

func ContextTrace

func ContextTrace(ctx context.Context) Trace

ContextTrace returns Trace associated with ctx. If there is no Trace associated with ctx then zero value of Trace is returned.

func (Trace) Compose

func (t Trace) Compose(x Trace) (ret Trace)

Compose returns a new Trace which has functional fields composed both from t and x.

type TxDoer

type TxDoer struct {
	DB      *sql.DB
	Options *sql.TxOptions

	// RetryConfig allows to override retry parameters from DB.
	RetryConfig *RetryConfig
}

TxDoer contains options for retrying transactions.

func (TxDoer) Do

func (d TxDoer) Do(ctx context.Context, f TxOperationFunc) (err error)

Do starts a transaction and calls f with it. If f() call returns a retryable error, it repeats it accordingly to retry configuration that TxDoer's DB driver holds.

Note that callers should mutate state outside of f carefully and keeping in mind that f could be called again even if no error returned – transaction commitment can be failed:

var results []int
ydbsql.DoTx(ctx, db, TxOperationFunc(func(ctx context.Context, tx *sql.Tx) error {
    // Reset resulting slice to prevent duplicates when retry occured.
    results = results[:0]

    rows, err := tx.QueryContext(...)
    if err != nil {
        // handle error
    }
    for rows.Next() {
        results = append(results, ...)
    }
    return rows.Err()
}))

type TxOperationFunc

type TxOperationFunc func(context.Context, *sql.Tx) error

type TzDate

type TzDate time.Time

func (*TzDate) Scan

func (d *TzDate) Scan(x interface{}) error

func (TzDate) Value

func (d TzDate) Value() ydb.Value

type TzDatetime

type TzDatetime time.Time

func (*TzDatetime) Scan

func (d *TzDatetime) Scan(x interface{}) error

func (TzDatetime) Value

func (d TzDatetime) Value() ydb.Value

type TzTimestamp

type TzTimestamp time.Time

func (*TzTimestamp) Scan

func (d *TzTimestamp) Scan(x interface{}) error

func (TzTimestamp) Value

func (d TzTimestamp) Value() ydb.Value

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL