driver

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2024 License: Apache-2.0, BSD-2-Clause, BSD-3-Clause, + 7 more Imports: 21 Imported by: 0

README

FlightSQL driver

A FlightSQL-Driver for Go's database/sql package. This driver is a lightweight wrapper around the FlightSQL client in pure Go. It provides all advantages of a database/sql driver like automatic connection pooling, transactions combined with ease of use (see (#usage)).



Prerequisites

  • Go 1.17+
  • Installation via go get -u github.com/joe-at-startupmedia/go-arrow/arrow/flight/flightsql
  • Backend speaking FlightSQL

Usage

Go FlightQL Driver is an implementation of Go's database/sql/driver interface to use the database/sql framework. The driver is registered as flightsql and configured using a data-source name (DSN).

A basic example using a SQLite backend looks like this

import (
    "database/sql"
    "time"

    _ "github.com/joe-at-startupmedia/go-arrow/arrow/flight/flightsql"
)

// Open the connection to an SQLite backend
db, err := sql.Open("flightsql", "flightsql://localhost:12345?timeout=5s")
if err != nil {
    panic(err)
}
// Make sure we close the connection to the database
defer db.Close()

// Use the connection e.g. for querying
rows, err := db.Query("SELECT * FROM mytable")
if err != nil {
    panic(err)
}
// ...

Data Source Name (DSN)

A Data Source Name has the following format:

flightsql://[user[:password]@]<address>[:port][?param1=value1&...&paramN=valueN]

The data-source-name (DSN) requires the address of the backend with an optional port setting. The user and password parameters are passed to the backend as GRPC Basic-Auth headers. If your backend requires a token based authentication, please use a token parameter (see common parameters below).

Please note: All parameters are case-sensitive!

Alternatively to specifying the DSN directly you can use the DriverConfig structure to generate the DSN string. See the Driver config usage section for details.

Common parameters

The following common parameters exist

token

The token parameter can be used to specify the token for token-based authentication. The value is passed on to the backend as a GRPC Bearer-Auth header.

timeout

The timeout parameter can be set using a duration string e.g. timeout=5s to limit the maximum time an operation can take. This prevents calls that wait forever, e.g. if the backend is down or a query is taking very long. When not set, the driver will use an infinite timeout.

tls

The tls parameter allows to enable and customize Transport-Layer-Security settings. There are some special values for the parameters:

  • disabled or false will disable TLS for this server connection. In this case all other settings are ignored.
  • enabled or true will force TLS for this server connection. In this case the system settings for trusted CAs etc will be used.
  • skip-verify will enable TLS for this server connection but will not verify the server certificate. This is a security risk and should not be used!

Any other value will be interpreted as the name of a custom configuration. Those configurations must be registered either by creating the DSN from configuration or by calling RegisterTLSConfig() (see TLS setup for details).

Driver config usage

Alternatively to specifying the DSN directly you can fill the DriverConfig structure and generate the DSN out of this. Here is some example

package main

import (
    "database/sql"
    "log"
    "time"

    "github.com/joe-at-startupmedia/go-arrow/arrow/flight/flightsql"
)

func main() {
    config := flightsql.DriverConfig{
        Address: "localhost:12345",
        Token:   "your token",
        Timeout: 10 * time.Second,
        Params: map[string]string{
            "my-custom-parameter": "foobar",
        },
    }
    db, err := sql.Open("flightsql", config.DSN())
    if err != nil {
        log.Fatalf("open failed: %v", err)
    }
    defer db.Close()

    ...
}

TLS setup

By specifying the tls parameter you can enable Transport-Layer-Security. Using tls=enabled the system settings are used for verifying the server's certificate. Custom TLS configurations, e.g. when using self-signed certificates, are referenced by a user-selected name. The underlying TLS configuration needs to be registered (using the same name) in two ways.

TLS setup using DriverConfig

The first way is to create a DriverConfig with the TLSConfig field set to the custom config and TLSConfigName set to the chosen name. For example

    ...

    config := flightsql.DriverConfig{
        Address: "localhost:12345",
        TLSEnabled:    true,
        TLSConfigName: "myconfig",
        TLSConfig: &tls.Config{
            MinVersion: tls.VersionTLS12,
        },
    }
    dsn := config.DSN()

    ...

will enable TLS forcing the minimum TLS version to 1.2. This custom config will be registered with the name myconfig and the resulting DSN reads

flightsql://localhost:12345?tls=myconfig`

If the TLSConfigName is omitted a random unique name (UUID) is generated and referenced in the DSN. This prevents errors from using an already registered name leading to errors.

TLS setup using manual registration

The second alternative is the manual registration of the custom TLS configuration. In this case you need to call RegisterTLSConfig() in your code

    myconfig := &tls.Config{MinVersion: tls.VersionTLS12}
    if err := flightsql.RegisterTLSConfig("myconfig", myconfig); err != nil {
        ...
    }
    dsn := "flightsql://localhost:12345?tls=myconfig"

    ...

This will register the custom configuration, constraining the minimum TLS version, as myconfig and then references the registered configuration by name in the DSN. You can reuse the same TLS configuration by registering once and then reference in multiple DSNs. Registering multiple configurations with the same name will throw an error to prevent unintended side-effects due to the driver-global registry.

Documentation

Overview

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotSupported          = errors.New("not supported")
	ErrOutOfRange            = errors.New("index out of range")
	ErrTransactionInProgress = errors.New("transaction still in progress")
	ErrRegistryEntryExists   = errors.New("entry already exists")
	ErrRegistryNoEntry       = errors.New("entry not registered")
)

Functions

func GetTLSConfig

func GetTLSConfig(name string) (*tls.Config, bool)

func RegisterTLSConfig

func RegisterTLSConfig(name string, cfg *tls.Config) error

func UnregisterTLSConfig

func UnregisterTLSConfig(name string) error

Types

type Connection

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

func (*Connection) Begin

func (c *Connection) Begin() (driver.Tx, error)

Begin starts and returns a new transaction.

func (*Connection) BeginTx

func (c *Connection) BeginTx(ctx context.Context, opts sql.TxOptions) (driver.Tx, error)

func (*Connection) Close

func (c *Connection) Close() error

Close invalidates and potentially stops any current prepared statements and transactions, marking this connection as no longer in use.

func (*Connection) Prepare

func (c *Connection) Prepare(query string) (driver.Stmt, error)

Prepare returns a prepared statement, bound to this connection.

func (*Connection) PrepareContext

func (c *Connection) PrepareContext(ctx context.Context, query string) (driver.Stmt, error)

PrepareContext returns a prepared statement, bound to this connection. context is for the preparation of the statement, it must not store the context within the statement itself.

func (*Connection) QueryContext

func (c *Connection) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error)

type Connector

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

func (*Connector) Configure

func (c *Connector) Configure(config *DriverConfig) error

Configure the driver with the corresponding config

func (*Connector) Connect

func (c *Connector) Connect(ctx context.Context) (driver.Conn, error)

Connect returns a connection to the database.

func (*Connector) Driver

func (c *Connector) Driver() driver.Driver

Driver returns the underlying Driver of the Connector, mainly to maintain compatibility with the Driver method on sql.DB.

type Driver

type Driver struct{}

func (*Driver) Open

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

Open returns a new connection to the database.

func (*Driver) OpenConnector

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

OpenConnector must parse the name in the same format that Driver.Open parses the name parameter.

type DriverConfig

type DriverConfig struct {
	Address  string
	Username string
	Password string
	Token    string
	Timeout  time.Duration
	Params   map[string]string

	TLSEnabled    bool
	TLSConfigName string
	TLSConfig     *tls.Config
}

func NewDriverConfigFromDSN

func NewDriverConfigFromDSN(dsn string) (*DriverConfig, error)

func (*DriverConfig) DSN

func (config *DriverConfig) DSN() string

type Result

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

func (*Result) LastInsertId

func (r *Result) LastInsertId() (int64, error)

LastInsertId returns the database's auto-generated ID after, for example, an INSERT into a table with primary key.

func (*Result) RowsAffected

func (r *Result) RowsAffected() (int64, error)

RowsAffected returns the number of rows affected by the query.

type Rows

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

func (*Rows) Close

func (r *Rows) Close() error

Close closes the rows iterator.

func (*Rows) Columns

func (r *Rows) Columns() []string

Columns returns the names of the columns.

func (*Rows) Next

func (r *Rows) Next(dest []driver.Value) error

Next is called to populate the next row of data into the provided slice. The provided slice will be the same size as the Columns() are wide.

Next should return io.EOF when there are no more rows.

The dest should not be written to outside of Next. Care should be taken when closing Rows not to modify a buffer held in dest.

type Stmt

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

func (*Stmt) Close

func (s *Stmt) Close() error

Close closes the statement.

func (*Stmt) Exec

func (s *Stmt) Exec(args []driver.Value) (driver.Result, error)

Exec executes a query that doesn't return rows, such as an INSERT or UPDATE.

func (*Stmt) ExecContext

func (s *Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error)

ExecContext executes a query that doesn't return rows, such as an INSERT or UPDATE.

func (*Stmt) NumInput

func (s *Stmt) NumInput() int

NumInput returns the number of placeholder parameters.

func (*Stmt) Query

func (s *Stmt) Query(args []driver.Value) (driver.Rows, error)

Query executes a query that may return rows, such as a SELECT.

func (*Stmt) QueryContext

func (s *Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error)

QueryContext executes a query that may return rows, such as a SELECT.

type Tx

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

func (*Tx) Commit

func (t *Tx) Commit() error

func (*Tx) Rollback

func (t *Tx) Rollback() error

Jump to

Keyboard shortcuts

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