exasol

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2022 License: MIT Imports: 33 Imported by: 4

README

Exasol Go SQL Driver

Go Reference

Quality Gate Status

Maintainability Rating Bugs Code Smells Coverage

This repository contains a Go library for connection to the Exasol database.

This library uses the standard Golang SQL driver interface for easy use.

Usage

Create Connection
With Exasol Config

We recommend using a provided builder to build a connection string:

package main

import (
    "database/sql"
    "github.com/exasol/exasol-driver-go"
)

func main() {
    database, err := sql.Open("exasol", exasol.NewConfig("<username>", "<password>")
                                              .Port(<port>)
                                              .Host("<host>")
                                              .String())
    // ...
}
With Exasol DSN

There is also a way to build the connection string without the builder:

package main

import (
    "database/sql"
    _ "github.com/exasol/exasol-driver-go"
)

func main() {
    database, err := sql.Open("exasol",
            "exa:<host>:<port>;user=<username>;password=<password>")
    // ...
}
Execute Statement
result, err := exasol.Exec(`
    INSERT INTO CUSTOMERS
    (NAME, CITY)
    VALUES('Bob', 'Berlin');`)
Query Statement
rows, err := exasol.Query("SELECT * FROM CUSTOMERS")
Use Prepared Statements
preparedStatement, err := exasol.Prepare(`
    INSERT INTO CUSTOMERS
    (NAME, CITY)
    VALUES(?, ?)`)
result, err = preparedStatement.Exec("Bob", "Berlin")
preparedStatement, err := exasol.Prepare("SELECT * FROM CUSTOMERS WHERE NAME = ?")
rows, err := preparedStatement.Query("Bob")

Transaction Commit and Rollback

To control a transaction state manually, you would need to disable autocommit (enabled by default):

database, err := sql.Open("exasol",
                "exa:<host>:<port>;user=<username>;password=<password>;autocommit=0")
// or
database, err := sql.Open("exasol", exasol.NewConfig("<username>", "<password>")
                                          .Port(<port>)
                                          .Host("<host>")
                                          .Autocommit(false)
                                          .String())

After that you can begin a transaction:

transaction, err := exasol.Begin()
result, err := transaction.Exec( ... )
result2, err := transaction.Exec( ... )

To commit a transaction use Commit():

err = transaction.Commit()

To rollback a transaction use Rollback():

err = transaction.Rollback()

Import local CSV files

Use the sql driver to load data into your Exasol Database.

!! Limitation !!

Only import of CSV files is supported at the moment.
result, err := exasol.Exec(`
IMPORT INTO CUSTOMERS FROM LOCAL CSV FILE './testData/data.csv' FILE './testData/data_part2.csv' 
 COLUMN SEPARATOR = ';' 
 ENCODING = 'UTF-8' 
 ROW SEPARATOR = 'LF'
`)

Connection String

The golang Driver uses the following URL structure for Exasol:

exa:<host>[,<host_1>]...[,<host_n>]:<port>[;<prop_1>=<value_1>]...[;<prop_n>=<value_n>]

Host-Range-Syntax is supported (e.g. exasol1..3). A range like exasol1..exasol3 is not valid.

Supported Driver Properties
Property Value Default Description
autocommit 0=off, 1=on 1 Switch autocommit on or off.
clientname string Go client Tell the server the application name.
clientversion string Tell the server the version of the application.
compression 0=off, 1=on 0 Switch data compression on or off.
encryption 0=off, 1=on 1 Switch automatic encryption on or off.
validateservercertificate 0=off, 1=on 1 TLS certificate verification. Disable it if you want to use a self-signed or invalid certificate (server side).
certificatefingerprint string Expected fingerprint of the server's TLS certificate. See below for details.
fetchsize numeric, >0 128*1024 Amount of data in kB which should be obtained by Exasol during a fetch. The application can run out of memory if the value is too high.
password string Exasol password.
resultsetmaxrows numeric Set the max amount of rows in the result set.
schema string Exasol schema name.
user string Exasol username.
Configuring TLS

We recommend to always enable TLS encryption. This is on by default, but you can enable it explicitly via driver property encryption=1 or config.Encryption(true).

There are two driver properties that control how TLS certificates are verified: validateservercertificate and certificatefingerprint. You have these three options depending on your setup:

  • With validateservercertificate=1 (or config.ValidateServerCertificate(true)) the driver will return an error for any TLS errors (e.g. unknown certificate or invalid hostname).

    Use this when the database has a CA-signed certificate. This is the default behavior.

  • With validateservercertificate=1;certificatefingerprint=<fingerprint> (or config.ValidateServerCertificate(true).CertificateFingerprint("<fingerprint>")) you can specify the fingerprint (i.e. the SHA256 checksum) of the server's certificate.

    This is useful when the database has a self-signed certificate with invalid hostname but you still want to verify connecting to the corrrect host.

    Note: You can find the fingerprint by first specifiying an invalid fingerprint and connecting to the database. The error will contain the actual fingerprint.

  • With validateservercertificate=1 (or config.ValidateServerCertificate(false)) the driver will ignore any TLS certificate errors.

    Use this if the server uses a self-signed certificate and you don't know the fingerprint. This is not recommended.

Information for Users

Testing / Development

Run unit tests only:

go test ./... -short

Run unit tests and integration tests:

For running the integrations tests you need Docker installed.

go test ./...

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidConn              = newDriverErr(exaerror.New("E-EGOD-1").Message("invalid connection"))
	ErrClosed                   = newDriverErr(exaerror.New("E-EGOD-2").Message("connection was closed"))
	ErrMalformedData            = newDriverErr(exaerror.New("E-EGOD-3").Message("malformed result"))
	ErrAutocommitEnabled        = newDriverErr(exaerror.New("E-EGOD-4").Message("begin not working when autocommit is enabled"))
	ErrInvalidValuesCount       = newDriverErr(exaerror.New("E-EGOD-5").Message("invalid value count for prepared status"))
	ErrNoLastInsertID           = newDriverErr(exaerror.New("E-EGOD-6").Message("no LastInsertId available"))
	ErrNamedValuesNotSupported  = newDriverErr(exaerror.New("E-EGOD-7").Message("named parameters not supported"))
	ErrLoggerNil                = newDriverErr(exaerror.New("E-EGOD-8").Message("logger is nil"))
	ErrMissingServerCertificate = newDriverErr(exaerror.New("E-EGOD-9").
								Message("server did not return certificates"))
	ErrInvalidProxyConn = newDriverErr(exaerror.New("E-EGOD-26").
						Message("could not create proxy connection to import file"))
	ErrInvalidImportQuery = newDriverErr(exaerror.New("E-EGOD-27").
							Message("could not parse import query"))
)

Various errors the driver might return. Can change between driver versions.

Functions

func SetLogger

func SetLogger(logger Logger) error

SetLogger is used to set the logger for critical errors. The initial logger is os.Stderr.

Types

type Attributes

type Attributes struct {
	Autocommit                  *bool  `json:"autocommit,omitempty"`
	CompressionEnabled          *bool  `json:"compressionEnabled,omitempty"`
	CurrentSchema               string `json:"currentSchema,omitempty"`
	DateFormat                  string `json:"dateFormat,omitempty"`
	DateLanguage                string `json:"dateLanguage,omitempty"`
	DatetimeFormat              string `json:"datetimeFormat,omitempty"`
	DefaultLikeEscapeCharacter  string `json:"defaultLikeEscapeCharacter,omitempty"`
	FeedbackInterval            int    `json:"feedbackInterval,omitempty"`
	NumericCharacters           string `json:"numericCharacters,omitempty"`
	OpenTransaction             *bool  `json:"openTransaction,omitempty"`
	QueryTimeout                int    `json:"queryTimeout,omitempty"`
	SnapshotTransactionsEnabled *bool  `json:"snapshotTransactionsEnabled,omitempty"`
	TimestampUtcEnabled         *bool  `json:"timestampUtcEnabled,omitempty"`
	Timezone                    string `json:"timezone,omitempty"`
	TimeZoneBehavior            string `json:"timeZoneBehavior,omitempty"`
	ResultSetMaxRows            int    `json:"resultSetMaxRows,omitempty"`
}

type AuthCommand

type AuthCommand struct {
	Username         string     `json:"username"`
	Password         string     `json:"password"`
	UseCompression   bool       `json:"useCompression"`
	SessionID        int        `json:"sessionId,omitempty"`
	ClientName       string     `json:"clientName,omitempty"`
	DriverName       string     `json:"driverName,omitempty"`
	ClientOs         string     `json:"clientOs,omitempty"`
	ClientOsUsername string     `json:"clientOsUsername,omitempty"`
	ClientLanguage   string     `json:"clientLanguage,omitempty"`
	ClientVersion    string     `json:"clientVersion,omitempty"`
	ClientRuntime    string     `json:"clientRuntime,omitempty"`
	Attributes       Attributes `json:"attributes,omitempty"`
}

type AuthResponse

type AuthResponse struct {
	SessionID             int    `json:"sessionId"`
	ProtocolVersion       int    `json:"protocolVersion"`
	ReleaseVersion        string `json:"releaseVersion"`
	DatabaseName          string `json:"databaseName"`
	ProductName           string `json:"productName"`
	MaxDataMessageSize    int    `json:"maxDataMessageSize"`
	MaxIdentifierLength   int    `json:"maxIdentifierLength"`
	MaxVarcharLength      int    `json:"maxVarcharLength"`
	IdentifierQuoteString string `json:"identifierQuoteString"`
	TimeZone              string `json:"timeZone"`
	TimeZoneBehavior      string `json:"timeZoneBehavior"`
}

type BaseResponse

type BaseResponse struct {
	Status       string          `json:"status"`
	ResponseData json.RawMessage `json:"responseData"`
	Exception    *Exception      `json:"exception"`
}

type ClosePreparedStatementCommand

type ClosePreparedStatementCommand struct {
	Command
	StatementHandle int        `json:"statementHandle"`
	Attributes      Attributes `json:"attributes,omitempty"`
}

type CloseResultSetCommand

type CloseResultSetCommand struct {
	Command
	ResultSetHandles []int      `json:"resultSetHandles"`
	Attributes       Attributes `json:"attributes,omitempty"`
}

type Command

type Command struct {
	Command string `json:"command"`
}

type CreatePreparedStatementCommand

type CreatePreparedStatementCommand struct {
	Command
	SQLText    string     `json:"sqlText"`
	Attributes Attributes `json:"attributes,omitempty"`
}

type CreatePreparedStatementResponse

type CreatePreparedStatementResponse struct {
	StatementHandle int           `json:"statementHandle"`
	ParameterData   ParameterData `json:"parameterData,omitempty"`
}

type DSNConfig

type DSNConfig struct {
	Host                      string
	Port                      int
	User                      string
	Password                  string
	Autocommit                *bool
	Encryption                *bool
	Compression               *bool
	ClientName                string
	ClientVersion             string
	FetchSize                 int
	ValidateServerCertificate *bool
	CertificateFingerprint    string
	Schema                    string
	ResultSetMaxRows          int
	// contains filtered or unexported fields
}

func ParseDSN added in v0.3.0

func ParseDSN(dsn string) (*DSNConfig, error)

func (*DSNConfig) ToDSN added in v0.3.0

func (c *DSNConfig) ToDSN() string

type DSNConfigBuilder added in v0.3.0

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

func NewConfig

func NewConfig(user, password string) *DSNConfigBuilder

func (*DSNConfigBuilder) Autocommit added in v0.3.0

func (c *DSNConfigBuilder) Autocommit(enabled bool) *DSNConfigBuilder

func (*DSNConfigBuilder) CertificateFingerprint added in v0.3.0

func (c *DSNConfigBuilder) CertificateFingerprint(fingerprint string) *DSNConfigBuilder

func (*DSNConfigBuilder) ClientName added in v0.3.0

func (c *DSNConfigBuilder) ClientName(name string) *DSNConfigBuilder

func (*DSNConfigBuilder) ClientVersion added in v0.3.0

func (c *DSNConfigBuilder) ClientVersion(version string) *DSNConfigBuilder

func (*DSNConfigBuilder) Compression added in v0.3.0

func (c *DSNConfigBuilder) Compression(enabled bool) *DSNConfigBuilder

func (*DSNConfigBuilder) Encryption added in v0.3.0

func (c *DSNConfigBuilder) Encryption(enabled bool) *DSNConfigBuilder

func (*DSNConfigBuilder) FetchSize added in v0.3.0

func (c *DSNConfigBuilder) FetchSize(size int) *DSNConfigBuilder

func (*DSNConfigBuilder) Host added in v0.3.0

func (c *DSNConfigBuilder) Host(host string) *DSNConfigBuilder

func (*DSNConfigBuilder) Port added in v0.3.0

func (c *DSNConfigBuilder) Port(port int) *DSNConfigBuilder

func (*DSNConfigBuilder) ResultSetMaxRows added in v0.3.0

func (c *DSNConfigBuilder) ResultSetMaxRows(maxRows int) *DSNConfigBuilder

func (*DSNConfigBuilder) Schema added in v0.3.0

func (c *DSNConfigBuilder) Schema(schema string) *DSNConfigBuilder

func (*DSNConfigBuilder) String added in v0.3.0

func (c *DSNConfigBuilder) String() string

func (*DSNConfigBuilder) ValidateServerCertificate added in v0.3.0

func (c *DSNConfigBuilder) ValidateServerCertificate(validate bool) *DSNConfigBuilder

type DriverErr

type DriverErr string

func (DriverErr) Error

func (e DriverErr) Error() string

type ExasolDriver

type ExasolDriver struct{}

func (ExasolDriver) Open

func (e ExasolDriver) Open(dsn string) (driver.Conn, error)

func (ExasolDriver) OpenConnector

func (e ExasolDriver) OpenConnector(dsn string) (driver.Connector, error)

type Exception

type Exception struct {
	Text    string `json:"text"`
	SQLCode string `json:"sqlCode"`
}

type ExecutePreparedStatementCommand

type ExecutePreparedStatementCommand struct {
	Command
	StatementHandle int              `json:"statementHandle"`
	NumColumns      int              `json:"numColumns,omitempty"`
	NumRows         int              `json:"numRows"`
	Columns         []SQLQueryColumn `json:"columns,omitempty"`
	Data            [][]interface{}  `json:"data"`
	Attributes      Attributes       `json:"attributes,omitempty"`
}

type FetchCommand

type FetchCommand struct {
	Command
	ResultSetHandle int `json:"resultSetHandle"`
	StartPosition   int `json:"startPosition"`
	NumBytes        int `json:"numBytes"`
}

type Logger

type Logger interface {
	Print(v ...interface{})
	Printf(format string, v ...interface{})
}

Logger is used to log critical error messages.

type LoginCommand

type LoginCommand struct {
	Command
	ProtocolVersion int        `json:"protocolVersion"`
	Attributes      Attributes `json:"attributes,omitempty"`
}

type ParameterData

type ParameterData struct {
	NumColumns int              `json:"numColumns"`
	Columns    []SQLQueryColumn `json:"columns"`
	SQLQueriesResponse
}

type PublicKeyResponse

type PublicKeyResponse struct {
	PublicKeyPem      string `json:"publicKeyPem"`
	PublicKeyModulus  string `json:"publicKeyModulus"`
	PublicKeyExponent string `json:"publicKeyExponent"`
}

type SQLCommand

type SQLCommand struct {
	Command
	SQLText    string     `json:"sqlText"`
	Attributes Attributes `json:"attributes,omitempty"`
}

type SQLQueriesResponse

type SQLQueriesResponse struct {
	NumResults int               `json:"numResults"`
	Results    []json.RawMessage `json:"results"`
}

type SQLQueryColumn

type SQLQueryColumn struct {
	Name     string             `json:"name"`
	DataType SQLQueryColumnType `json:"dataType"`
}

type SQLQueryColumnType

type SQLQueryColumnType struct {
	Type              string  `json:"type"`
	Precision         *int64  `json:"precision,omitempty"`
	Scale             *int64  `json:"scale,omitempty"`
	Size              *int64  `json:"size,omitempty"`
	CharacterSet      *string `json:"characterSet,omitempty"`
	WithLocalTimeZone *bool   `json:"withLocalTimeZone,omitempty"`
	Fraction          *int    `json:"fraction,omitempty"`
	SRID              *int    `json:"srid,omitempty"`
}

type SQLQueryResponseResultSet

type SQLQueryResponseResultSet struct {
	ResultType string                        `json:"resultType"`
	ResultSet  SQLQueryResponseResultSetData `json:"resultSet"`
}

type SQLQueryResponseResultSetData

type SQLQueryResponseResultSetData struct {
	ResultSetHandle  int              `json:"resultSetHandle"`
	NumColumns       int              `json:"numColumns,omitempty"`
	NumRows          int              `json:"numRows"`
	NumRowsInMessage int              `json:"numRowsInMessage"`
	Columns          []SQLQueryColumn `json:"columns,omitempty"`
	Data             [][]interface{}  `json:"data"`
}

type SQLQueryResponseRowCount

type SQLQueryResponseRowCount struct {
	ResultType string `json:"resultType"`
	RowCount   int    `json:"rowCount"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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