rdb: github.com/kardianos/rdb Index | Files | Directories

package rdb

import "github.com/kardianos/rdb"

SQL Relational Database Client.

A query is defined through a *Command. Do not create a new *Command structure every time a query is run, but create a *Command for each query once. Once created a *Command structure shouldn't be modified while it might be used.

The Arity field in *Command controls how the number of rows are handled. If the Arity is zero, the result is automatically closed after execution. If the Arity is one, the result is closed after reading the first row.

Depending on the driver, the name fields "N" may be optional and the order of of the parameters or values used. Refer to each driver's documentation for more information. To pass in a NULL parameter, use "rdb.TypeNull" as the value.

Result.Prep should be called before Scan on each row. To prepare multiple values Result.Scan(...) can be used to scan into value by index all at once. Some drivers will support io.Writer for some data types. If a value is not prep'ed, the value will be stored in a row buffer until the next Result.Scan().

Simple example:

cmd := &rdb.Command{
	Sql: `select * from Account where ID = :ID;`,
	Arity: rdb.OneMust,
}
res, err := db.Query(cmd, rdb.Param{Name: "ID", Value: 2})
if err != nil {
	return err
}
// Next() is not required.
var id int
err = res.Scan(&id)
if err != nil {
	return err
}

Index

Package Files

config.go connection.go converter.go doc.go driver.go errors.go params.go pool.go register.go result.go transaction.go type.go valuer.go

Constants

const (
    TypeDriverThresh = 0x00010000
)

Variables

var ArityError = errors.New("Result row count does not match desired arity.")
var ErrTimeout = pools.ErrTimeout
var NotImplemented = errors.New("The feature has not been implemented.")

Should be returned by a driver that doesn't implement a feature.

var PreparedTokenNotValid = errors.New("The prepared token is not valid.")
var ScanNullError = errors.New("Can only scan NULL value into a Nullable type.")

func AssignValue Uses

func AssignValue(c *Column, outValue Nullable, prep interface{}, assign Assigner) error

func Register Uses

func Register(name string, dr Driver)

Panics if called twice with the same name. Make the driver instance available clients.

type Arity Uses

type Arity byte
const (
    Any Arity = 0

    ArityMust Arity = 16

    Zero Arity = 1 // Close the result after the query executes.
    One  Arity = 2 // Close the result after one row.

    // Close the result after the query executes,
    // return an error if any rows are returned.
    ZeroMust Arity = Zero | ArityMust

    // Close the result after one row,
    // return an error if more or less then one row is returned.
    OneMust Arity = One | ArityMust
)

The number of rows to expect from a command.

type Assigner Uses

type Assigner func(input, output interface{}) (handled bool, err error)

TODO: Rename to DriverAssigner and document better. Assigner can be used by the driver to put special values directly into prepped value pointer.

type Column Uses

type Column struct {
    Name      string // Columnn name.
    Index     int    // Column zero based index as appearing in result.
    Type      Type   // The data type as reported from the driver.
    Generic   Type   // The generic data type as reported from the driver.
    Length    int    // The length of the column as it makes sense per type.
    Unlimit   bool   // Provides near unlimited length.
    Nullable  bool   // True if the column type can be null.
    Key       bool   // True if the column is part of the key.
    Serial    bool   // True if the column is auto-incrementing.
    Precision int    // For decimal types, the precision.
    Scale     int    // For types with scale, including decimal.
}

Information about the column as reported by the database.

type ColumnConverter Uses

type ColumnConverter func(column *Column, nullable *Nullable) error

ColumnConverter converts between value types.

type Command Uses

type Command struct {
    Context context.Context

    // The SQL to be used in the command.
    Sql string

    // Number of rows expected.
    //   If Arity is One or OneOnly, only the first row is returned.
    //   If Arity is OneOnly, if more results are returned an error is returned.
    //   If Arity is Zero or ZeroOnly, no rows are returned.
    //   If Arity is ZeroOnnly, if any results are returned an error is returned.
    Arity Arity

    // Optional fields to specify output marshal.
    Fields []Field

    // If set to true silently truncates text longer then the field.
    // If this is set to false text truncation will result in an error.
    TruncLongText bool

    // If true the connection will attempt to lookup any cached prepared
    // identifier. If the cached identifier is not found or if it is found
    // to be invalid, it is renewed.
    // When the connection or connection pool is closed any prepared statements
    // are un-prepared.
    Prepare bool

    // Set the isolation level for the query or transaction.
    IsoLevel IsolationLevel

    // Converter returns conversion functions per column or parameter. If nil
    // no conversion is performed.
    Converter Converter

    // Optional name of the command. May be used if logging.
    Name string

    // QueryTimeout is the timeout for a query this command is executed in.
    // This is ignored if zero. If this is zero, the connection configuration
    // QueryTimeout field will be used if non-zero.
    QueryTimeout time.Duration

    // The duraction before the query is automatically closed. If negative,
    // autoclose is disabled. If zero, the default is used. If positive that
    // value is used.
    AutoClose time.Duration

    // Return strings as strings or bytes.
    StringMethod StringMethod
}

Command represents a SQL command and can be used from many different queries at the same time. The Command MUST be reused if the Prepare field is true.

type Config Uses

type Config struct {
    DriverName string

    Username string
    Password string
    Hostname string
    Port     int
    Instance string
    Database string // Initial database to connect to.

    // Timeout time for connection dial.
    // Zero for no timeout.
    DialTimeout time.Duration

    // Default timeout for each query if no timeout is
    // specified in the Command structure.
    QueryTimeout time.Duration

    // Time for an idle connection to be closed.
    // Zero if there should be no timeout.
    PoolIdleTimeout time.Duration

    // How many connection should be created at startup.
    // Valid range is (0 < init, init <= max).
    PoolInitCapacity int

    // Max number of connections to create.
    // Valid range is (0 < max).
    PoolMaxCapacity int

    // Require the driver to establish a secure connection.
    Secure bool

    // Do not require the secure connection to verify the remote host name.
    // Ignored if Secure is false.
    InsecureSkipVerify bool

    // ResetQuery is executed after the connection is reset.
    ResetQuery string

    KV  map[string]interface{}
}

Database connection configuration. Drivers may have additional properties held in KV. If a driver is file based, the file name should be in the "Instance" field.

func ParseConfigURL Uses

func ParseConfigURL(connectionString string) (*Config, error)

Provides a standard method to parse configuration options from a text. The instance field can also hold the filename in case of a file based connection.

driver://[username:password@][url[:port]]/[Instance]?db=mydatabase&opt1=valA&opt2=valB
sqlite:///C:/folder/file.sqlite3?opt1=valA&opt2=valB
sqlite:///srv/folder/file.sqlite3?opt1=valA&opt2=valB
ms://TESTU@localhost/SqlExpress?db=master&dial_timeout=3s

This will attempt to find the driver to load additional parameters.

Additional field options:
   db=<string>:                  Database
   dial_timeout=<time.Duration>: DialTimeout
   init_cap=<int>:               PoolInitCapacity
   max_cap=<int>:                PoolMaxCapacity
   idle_timeout=<time.Duration>: PoolIdleTimeout
   query_timeout=<time.Duration>:QueryTimeout

type ConnPool Uses

type ConnPool struct {
    OnAutoClose func(sql string)
    // contains filtered or unexported fields
}

Represents a connection or connection configuration to a database.

func Open Uses

func Open(config *Config) (*ConnPool, error)

func (*ConnPool) Begin Uses

func (cp *ConnPool) Begin() (*Transaction, error)

Begin starts a Transaction with the default isolation level.

func (*ConnPool) BeginLevel Uses

func (cp *ConnPool) BeginLevel(level IsolationLevel) (*Transaction, error)

BeginLevel starts a Transaction with the specified isolation level.

func (*ConnPool) Close Uses

func (cp *ConnPool) Close()

func (*ConnPool) Connection Uses

func (cp *ConnPool) Connection() (*Connection, error)

Connection returns a dedicated database connection from the connection pool.

func (*ConnPool) ConnectionInfo Uses

func (cp *ConnPool) ConnectionInfo() (*ConnectionInfo, error)

Returns the information specific to the connection.

func (*ConnPool) Ping Uses

func (cp *ConnPool) Ping() error

Will attempt to connect to the database and disconnect. Must not impact any existing connections.

func (*ConnPool) PoolAvailable Uses

func (cp *ConnPool) PoolAvailable() (capacity, available int)

func (*ConnPool) Query Uses

func (cp *ConnPool) Query(cmd *Command, params ...Param) (*Result, error)

Perform a query against the database. If values are not specified in the Command.Input[...].V, then they may be specified in the Value. Order may be used to match the existing parameters if the Value.N name is omitted.

type Connection Uses

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

func (*Connection) Active Uses

func (c *Connection) Active() bool

Return true if the connection has not been closed.

func (*Connection) Close Uses

func (c *Connection) Close() error

Close returns the underlying connection to the Connection Pool.

func (*Connection) Query Uses

func (c *Connection) Query(cmd *Command, params ...Param) (*Result, error)

Query executes a Command on the connection.

type ConnectionInfo Uses

type ConnectionInfo struct {
    Server, Protocol *semver.Version
}

type Converter Uses

type Converter interface {
    ColumnConverter(column *Column) ColumnConverter
    ConvertParam(param *Param) error
}

ColumnConverter is called once per column or output parameter to fetch the ColumnConverter function. Should the function ColumnConverter be nil, no conversion is performed. ConvertParam is called once per input parameter.

type Driver Uses

type Driver interface {
    // Open a database. An actual connection does not need to be established
    // at this time.
    Open(c *Config) (DriverConn, error)

    // Return information about the database drivers capabilities.
    // Should not reflect any actual server any connections to it.
    DriverInfo() *DriverInfo

    // Return the command to send a NOOP to the server.
    PingCommand() *Command
}

Driver is implemented by the database driver.

type DriverConn Uses

type DriverConn interface {
    // Close the underlying connection to the database.
    Close()

    Available() bool             // True if not currently in a connection pool.
    SetAvailable(available bool) // Set when adding or removing from connection pool.

    // Return version information regarding the currently connected server.
    ConnectionInfo() *ConnectionInfo

    // Read the next row from the connection. For each field in the row
    // call the Valuer.WriteField(...) method. Propagate the reportRow field.
    Scan() error

    // NextResult advances to the next result if there are multiple results.
    NextResult() (more bool, err error)

    // NextQuery stops the active query and gets the connection for the next one.
    NextQuery() (err error)

    // The isolation level is set by the command.
    // Should return "PreparedTokenNotValid" if the preparedToken was not recognized.
    Query(cmd *Command, params []Param, preparedToken interface{}, val DriverValuer) error

    Status() DriverConnStatus

    // Reset the connection to be ready for next connection.
    Reset(*Config) error

    // Happy Path:
    //  * Interface wants to prepare command, but doesn't have token.
    //  * Interface sends a conn Prepare requests and gets a token.
    //  * Interface uses token in query.
    //  * After some use, Interface unprepares command.
    //
    // Re-prepare Path:
    //  * Interface has a token and attempts to use it in query.
    //  * Query returns "the token is not valid" error (server restart?).
    //  * Interface attempts to re-prepare query.
    //  * Interface uses new token in Query. If that fails again, it should fail the query.
    Prepare(*Command) (preparedToken interface{}, err error)
    Unprepare(preparedToken interface{}) (err error)

    Begin(iso IsolationLevel) error
    Rollback(savepoint string) error
    Commit() error
    SavePoint(name string) error
}

Conn represents a database driver connection.

type DriverConnStatus Uses

type DriverConnStatus byte

TODO: Add states for transactions.

const (
    StatusDisconnected DriverConnStatus = iota
    StatusReady
    StatusQuery
    StatusResultDone
    StatusBulkCopy
)

type DriverInfo Uses

type DriverInfo struct {
    Options []*DriverOption
    DriverSupport
}

type DriverNotFound Uses

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

Exposed to help isolate error paths when starting a client.

func (DriverNotFound) Error Uses

func (dr DriverNotFound) Error() string

type DriverOption Uses

type DriverOption struct {
    Name string

    Description string
    Parse       func(input string) (interface{}, error)
}

type DriverSupport Uses

type DriverSupport struct {
    // PreparePerConn is set to true if prepared statements are local to
    // each connection. Set to false if prepared statements are global.
    PreparePerConn bool

    NamedParameter   bool // Supports named parameters.
    FluidType        bool // Like SQLite.
    MultipleResult   bool // Supports returning multiple result sets.
    SecureConnection bool // Supports a secure connection.
    BulkInsert       bool // Supports a fast bulk insert method.
    Notification     bool // Supports driver notifications.
    UserDataTypes    bool // Handles user supplied data types.
}

type DriverValue Uses

type DriverValue struct {
    Value    interface{}
    Null     bool
    MustCopy bool // If the Value is a common driver buffer, set to true.
    More     bool // True if more data is expected for the field.
    Chunked  bool // True if data is sent in chunks.
}

DriverValue used by the driver to report a field value. If a long field, such as a long byte array, it can be chunked directly into destination. If the driver is copying from a common buffer then the MustCopy field must be true so it is known it must be copied out.

type DriverValuer Uses

type DriverValuer interface {
    Columns([]*Column) error
    Done() error
    RowScanned()
    Message(*Message)
    WriteField(c *Column, value *DriverValue, assign Assigner) error
    RowsAffected(count uint64)
}

type ErrorColumnNotFound Uses

type ErrorColumnNotFound struct {
    At    string
    Name  string
    Index int
}

Used when a column lookup fails, either with a name or index.

func (ErrorColumnNotFound) Error Uses

func (err ErrorColumnNotFound) Error() string

type Errors Uses

type Errors []*Message

List of SQL errors returned by the server.

func (Errors) Error Uses

func (errs Errors) Error() string

type Field Uses

type Field struct {
    Name string // Optional Field Name.

    // Value to report if the driver reports a null value.
    Null interface{}
}

If the command output fields are specified, the Field output can help manage how the result rows are copied to.

type IsolationLevel Uses

type IsolationLevel byte
const (
    LevelDefault IsolationLevel = iota
    LevelReadUncommited
    LevelReadCommited
    LevelWriteCommited
    LevelRepeatableRead
    LevelSerializable
    LevelSnapshot
)

type Message Uses

type Message struct {
    Type       MessageType
    Message    string
    ServerName string
    ProcName   string
    LineNumber int32
    SqlState   string
    Number     int32
}

SQL errors reported by the server. Must always be wrapped by SqlErrors. This is why it doesn't satisfy the error interface.

func (*Message) String Uses

func (err *Message) String() string

type MessageType Uses

type MessageType byte
const (
    SqlError MessageType = iota
    SqlInfo
)

type NullType Uses

type NullType struct{}
var Null NullType

type Nullable Uses

type Nullable struct {
    Null  bool        // True if value is null.
    Value interface{} // Value, if any present.
}

Returned from GetN and GetxN. Represents a nullable type.

type Param Uses

type Param struct {
    // Optional parameter name.
    // All parameter names MUST NOT begin with a leading symbol. If required by
    // the backend the driver should insert.
    Name string

    // Parameter Type. Drivers may be able to infer this type.
    // Check the driver documentation used for more information.
    Type Type

    // Paremeter Length. Useful for variable length types that may check truncation.
    Length int

    // Value for input parameter.
    // If the value is an io.Reader it will read the value directly to the wire.
    Value interface{}

    // Set to true if the parameter is an output parameter.
    // If true, the value member should be provided through a pointer.
    Out bool

    // The following fields may go away.
    Null      bool
    Scale     int
    Precision int
}

If the N (Name) field is not specified is not specified, then the order of the parameter should be used if the driver supports it.

type Queryer Uses

type Queryer interface {
    Query(cmd *Command, params ...Param) (*Result, error)
}

Queryer allows passing either a ConnPool or a Transaction.

type Result Uses

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

Manages the life cycle of a query. The result must automaticly Close() if the command Arity is Zero after execution or after the first Scan() if Arity is One.

func (*Result) Close Uses

func (r *Result) Close() error

Results should automatically close when all rows have been read.

func (*Result) Get Uses

func (r *Result) Get(name string) interface{}

Use after Scan(). Can only pull fields which have not already been sent into a prepared value. Will panic if name is not a valid column name.

func (*Result) GetN Uses

func (r *Result) GetN(name string) Nullable

Use after Scan(). Can only pull fields which have not already been sent into a prepared value. Will panic if name is not a valid column name.

func (*Result) GetRowN Uses

func (r *Result) GetRowN() []Nullable

Use after Scan(). Can only pull fields which have not already been sent into a prepared value. Not all fields will be populated if some have been prepared.

func (*Result) Getx Uses

func (r *Result) Getx(index int) interface{}

Use after Scan(). Can only pull fields which have not already been sent into a prepared value. Will panic if index is not a valid column index.

func (*Result) GetxN Uses

func (r *Result) GetxN(index int) Nullable

Use after Scan(). Can only pull fields which have not already been sent into a prepared value. Will panic if index is not a valid column index.

func (*Result) Info Uses

func (r *Result) Info() []*Message

Informational messages. Do not call concurrently with Scan() or Done().

func (*Result) Next Uses

func (r *Result) Next() (more bool)

Optional to call. Determine if there is another row. Scan actually advances to the next row.

func (*Result) NextResult Uses

func (r *Result) NextResult() (more bool, err error)

func (*Result) Prep Uses

func (r *Result) Prep(name string, value interface{}) *Result

Prepare pointers to values to be populated by name using Prep. After preparing call Scan(). Will panic if name is not a valid column name.

func (*Result) Prepx Uses

func (r *Result) Prepx(index int, value interface{}) *Result

Prepare pointers to values to be populated by index using Prep. After preparing call Scan(). Will panic if index is not a valid column index.

func (*Result) RowsAffected Uses

func (r *Result) RowsAffected() uint64

func (*Result) Scan Uses

func (r *Result) Scan(values ...interface{}) error

Scans the row into a buffer that can be fetched with Get and scans directly into any prepared values. Return value "more" is false if no more rows. Results should automatically close when all rows have been read.

func (*Result) Schema Uses

func (r *Result) Schema() []*Column

Fetch the table schema.

type StringMethod Uses

type StringMethod byte

Return strings as.

const (
    StringAsString StringMethod = iota
    StringAsBytes
)

type Transaction Uses

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

Although nested transactions are unsupported, savepoints are supported. A transaction should end with either a Commit() or Rollback() call.

func (*Transaction) Active Uses

func (tran *Transaction) Active() bool

Return true if the transaction has not been either commited or entirely rolled back.

func (*Transaction) Commit Uses

func (tran *Transaction) Commit() error

Commit commits a one or more queries. If no queries have been run this just returns the connection without any action being taken.

func (*Transaction) Query Uses

func (tran *Transaction) Query(cmd *Command, params ...Param) (*Result, error)

func (*Transaction) Rollback Uses

func (tran *Transaction) Rollback() error

Rollback rolls back one or more queries. If no queries have been run this just returns the connection without any action being taken.

func (*Transaction) RollbackTo Uses

func (tran *Transaction) RollbackTo(savepoint string) error

Rollback to an existing savepoint. Commit or Rollback should still be called after calling RollbackTo.

func (*Transaction) SavePoint Uses

func (tran *Transaction) SavePoint(name string) error

Create a save point in the transaction.

type Type Uses

type Type uint32

Each driver should define its own Type over value TypeDriverThresh (65536). Values over TypeDriverThresh establish thier own namespace for types. Driver types are often limited to 16 bits so that leaves enough space Open for more then one type spaces or user types.

const (
    Text Type = 16 + iota
    Binary
    Bool
    Integer
    Float
    Decimal
    Time
    Other
)

Generic SQL types. Can be used in parameters. Reported in SqlColumn.Generic.

const (
    // Driver defaults for text varying lengths.
    // Specific character data types.
    TypeText        Type = 1024 + iota // Unicode text with varying length. Also nvarchar.
    TypeAnsiText                       // Ansi text with varying length. Also varchar.
    TypeVarChar                        // Unicode text with varying length. Also nvarchar.
    TypeAnsiVarChar                    // Ansi text with varying length. Also varchar.
    TypeChar                           // Unicode text with fixed length. Also nchar.
    TypeAnsiChar                       // Ansi text with fixed length. Also char.

    TypeBinary // Byte array.

    TypeBool   // Also bit.
    TypeUint8  // Also unsigned tiny int.
    TypeUint16 // Also unsigned small int.
    TypeUint32 // Also unsigned int.
    TypeUint64 // Also unsigned big int.
    TypeInt8   // Also tiny int.
    TypeInt16  // Also small int.
    TypeInt32  // Also int.
    TypeInt64  // Also big int.

    // Auto-incrementing integer.
    TypeSerial16
    TypeSerial32
    TypeSerial64

    TypeFloat32 // Floating point number, also real.
    TypeFloat64 // Floating point number, "double" width.

    TypeDecimal // Exact number with specified scale and precision.
    TypeMoney

    TypeTimestampz // Contains time, date, and time zone.
    TypeDuration   // Contains a span of time.
    TypeTime       // Only contains time of day.
    TypeDate       // Only contains a date.
    TypeTimestamp  // Only contains a time and, no time zone.

    TypeUUID // Also uniqueidentifier or GUID.

    TypeEnum
    TypeRange
    TypeArray
    TypeJson
    TypeXml
    TypeTable
)

Type constants are not represented in all database systems. Additional sql types may be recognized per driver, but such types must have a vlaue greater then TypeDriverThresh.

const (
    TypeUnknown Type = 0
)

func (Type) Driver Uses

func (t Type) Driver() bool

Returns true if this is a driver defined type.

func (Type) Generic Uses

func (t Type) Generic() bool

Generic returns true if the type is a generic type.

Directories

PathSynopsis
internal/poolsPackage pools provides functionality to manage and reuse resources like connections.
internal/pools/cachePackage cache implements a LRU cache.
internal/pools/sync2Package sync2 provides extra functionality along the same lines as sync.
internal/pools/timerPackage timer provides various enhanced timer functions.
internal/sbufferSingle-Buffer backing for readers.
internal/uconv
msMicrosoft SQL Server (MS SQL Server) TDS Protocol database client.
ms/batchProides batch functions for interacting with batched sql statements in the same file or string.
ms/ssrp
mustpackage must wraps the rdb database interface with one that returns errors with a panic.
semversemver holds standard version structure.
sqlPackage sql is API compatible with "database/sql" but uses the rdb driver and connection pool.
sql/driverPackage driver is a shim for "database/sql/driver".
tabletable give a logical in-memory buffer row a database table.

Package rdb imports 14 packages (graph) and is imported by 5 packages. Updated 2021-01-16. Refresh now. Tools for package owners.