Documentation ¶
Overview ¶
Package driver is a native Go SAP HANA driver implementation for the database/sql package. For the SAP HANA SQL Command Network Protocol Reference please see: https://help.sap.com/viewer/7e4aba181371442d9e4395e7ff71b777/2.0.03/en-US/9b9d8c894343424fac157c96dcb0a592.html
Example ¶
// SPDX-FileCopyrightText: 2014-2022 SAP SE // // SPDX-License-Identifier: Apache-2.0 package main import ( "database/sql" "log" // Register hdb driver. _ "github.com/SAP/go-hdb/driver" ) const ( driverName = "hdb" hdbDsn = "hdb://user:password@host:port" ) func main() { db, err := sql.Open(driverName, hdbDsn) if err != nil { log.Fatal(err) } defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
Example (BulkInsert) ¶
ExampleBulkInsert inserts 1000 rows into a database table.
The insert SQL command is "bulk insert" instead of "insert". After the insertion of the values a final stmt.Exec() without parameters must be executed.
Caution: Bulk statements need to be executed in the context of a transaction or connection to guarantee that that all statement operations are done within the same connection.
package main import ( "context" "database/sql" "fmt" "log" "github.com/SAP/go-hdb/driver" ) func main() { db := sql.OpenDB(driver.DefaultTestConnector()) defer db.Close() tableName := driver.RandomIdentifier("table_") // Create table. if _, err := db.Exec(fmt.Sprintf("create table %s (i integer, f float)", tableName)); err != nil { log.Fatal(err) } // Get connection for bulk insert. conn, err := db.Conn(context.Background()) if err != nil { log.Fatal(err) } defer conn.Close() // Prepare statement on basis of connection (bulk insert). stmt, err := conn.PrepareContext(context.Background(), fmt.Sprintf("bulk insert into %s values (?,?)", tableName)) if err != nil { log.Fatal(err) } defer stmt.Close() // Bulk insert. for i := 0; i < 1000; i++ { if _, err := stmt.Exec(i, float64(i)); err != nil { log.Fatal(err) } } // Call final stmt.Exec(). if _, err := stmt.Exec(); err != nil { log.Fatal(err) } // Select number of inserted rows. var numRow int if err := db.QueryRow(fmt.Sprintf("select count(*) from %s", tableName)).Scan(&numRow); err != nil { log.Fatal(err) } fmt.Print(numRow) // Drop table. if _, err := db.Exec(fmt.Sprintf("drop table %s", tableName)); err != nil { log.Fatal(err) } }
Output: 1000
Example (CallSimpleOut) ¶
ExampleCallSimpleOut creates a stored procedure with one output parameter and executes it. Stored procedures with output parameters must be executed by sql.Query or sql.QueryRow. For TestConnector see main_test.go.
const procOut = `create procedure %s (out message nvarchar(1024)) language SQLSCRIPT as begin message := 'Hello World!'; end ` db := sql.OpenDB(DefaultTestConnector()) defer db.Close() procedure := RandomIdentifier("procOut_") if _, err := db.Exec(fmt.Sprintf(procOut, procedure)); err != nil { // Create stored procedure. log.Fatal(err) } var out string if err := db.QueryRow(fmt.Sprintf("call %s(?)", procedure)).Scan(&out); err != nil { log.Fatal(err) } fmt.Print(out)
Output: Hello World!
Example (CallTableOut) ¶
ExampleCallTableOut creates a stored procedure with one table output parameter and executes it making use of sql.Rows scan parameters (non-legacy mode - *please see connector.SetLegacy(false)). Stored procedures with table output parameters must be executed by sql.Query as sql.QueryRow will close the query after execution and prevent querying output table values. For TestConnector see main_test.go.
const procTable = `create procedure %[1]s (out t %[2]s) language SQLSCRIPT as begin create local temporary table #test like %[2]s; insert into #test values('Hello, 世界'); insert into #test values('SAP HANA'); insert into #test values('Go driver'); t = select * from #test; drop table #test; end ` connector := NewTestConnector() // *Switch to non-legacy mode. connector.SetLegacy(false) db := sql.OpenDB(connector) defer db.Close() tableType := RandomIdentifier("TableType_") procedure := RandomIdentifier("ProcTable_") if _, err := db.Exec(fmt.Sprintf("create type %s as table (x nvarchar(256))", tableType)); err != nil { // Create table type. log.Fatal(err) } if _, err := db.Exec(fmt.Sprintf(procTable, procedure, tableType)); err != nil { // Create stored procedure. log.Fatal(err) } var tableRows sql.Rows // Scan variable of table output parameter. // Query stored procedure. rows, err := db.Query(fmt.Sprintf("call %s(?)", procedure)) if err != nil { log.Fatal(err) } defer rows.Close() if !rows.Next() { log.Fatal(rows.Err()) } if err := rows.Scan(&tableRows); err != nil { log.Fatal(err) } for tableRows.Next() { var x string if err := tableRows.Scan(&x); err != nil { log.Fatal(err) } fmt.Println(x) } if err := tableRows.Err(); err != nil { log.Fatal(err) }
Output: Hello, 世界 SAP HANA Go driver
Example (CallTableOutLegacy) ¶
ExampleCallTableOutLegacy creates a stored procedure with one table output parameter and executes it in legacy mode. Legacy mode: Stored procedures with table output parameters must be executed by sql.Query as sql.QueryRow will close the query after execution and prevent querying output table values. The scan type of a table output parameter is a string containing an opaque value to query table output values by standard sql.Query or sql.QueryRow methods. For TestConnector see main_test.go.
const procTable = `create procedure %[1]s (out t %[2]s) language SQLSCRIPT as begin create local temporary table #test like %[2]s; insert into #test values('Hello, 世界'); insert into #test values('SAP HANA'); insert into #test values('Go driver'); t = select * from #test; drop table #test; end ` connector := NewTestConnector() // *Switch to legacy mode. connector.SetLegacy(true) db := sql.OpenDB(connector) defer db.Close() tableType := RandomIdentifier("TableType_") procedure := RandomIdentifier("ProcTable_") if _, err := db.Exec(fmt.Sprintf("create type %s as table (x nvarchar(256))", tableType)); err != nil { // Create table type. log.Fatal(err) } if _, err := db.Exec(fmt.Sprintf(procTable, procedure, tableType)); err != nil { // Create stored procedure. log.Fatal(err) } var tableQuery string // Scan variable of table output parameter. // Query stored procedure. rows, err := db.Query(fmt.Sprintf("call %s(?)", procedure)) if err != nil { log.Fatal(err) } defer rows.Close() if !rows.Next() { log.Fatal(rows.Err()) } if err := rows.Scan(&tableQuery); err != nil { log.Fatal(err) } // Query stored procedure output table. tableRows, err := db.Query(tableQuery) if err != nil { log.Fatal(err) } defer tableRows.Close() for tableRows.Next() { var x string if err := tableRows.Scan(&x); err != nil { log.Fatal(err) } fmt.Println(x) } if err := tableRows.Err(); err != nil { log.Fatal(err) }
Output: Hello, 世界 SAP HANA Go driver
Example (ManyInsert) ¶
ExampleManyInsert inserts 1000 rows into a database table via a 'many' operation.
package main import ( "context" "database/sql" "fmt" "log" "github.com/SAP/go-hdb/driver" ) func main() { // Number of rows to be inserted into table. numRow := 1000 db := sql.OpenDB(driver.DefaultTestConnector()) defer db.Close() tableName := driver.RandomIdentifier("table_") // Create table. if _, err := db.Exec(fmt.Sprintf("create table %s (i integer, f double)", tableName)); err != nil { log.Fatal(err) } // Prepare statement. stmt, err := db.PrepareContext(context.Background(), fmt.Sprintf("insert into %s values (?, ?)", tableName)) if err != nil { log.Fatal(err) } defer stmt.Close() // Prepare data. data := make([][]interface{}, numRow) for i := 0; i < numRow; i++ { data[i] = []interface{}{i, float64(i)} } // Insert many. if _, err := stmt.Exec(data); err != nil { log.Fatal(err) } // Select number of inserted rows. if err := db.QueryRow(fmt.Sprintf("select count(*) from %s", tableName)).Scan(&numRow); err != nil { log.Fatal(err) } fmt.Print(numRow) // Drop table. if _, err := db.Exec(fmt.Sprintf("drop table %s", tableName)); err != nil { log.Fatal(err) } }
Output: 1000
Example (Query) ¶
TODO complete for named parameters
db := sql.OpenDB(DefaultTestConnector()) defer db.Close() table := RandomIdentifier("testNamedArg_") if _, err := db.Exec(fmt.Sprintf("create table %s (i integer, j integer)", table)); err != nil { log.Fatal(err) } var i = 0 if err := db.QueryRow(fmt.Sprintf("select count(*) from %s where i = :1 and j = :1", table), 1).Scan(&i); err != nil { log.Fatal(err) } if err := db.QueryRow(fmt.Sprintf("select count(*) from %s where i = ? and j = :3", table), 1, "soso", 2).Scan(&i); err != nil { log.Fatal(err) } fmt.Print(i)
Output: 0
Index ¶
- Constants
- Variables
- type Conn
- type Connector
- func NewBasicAuthConnector(host, username, password string) *Connector
- func NewConnector() *Connector
- func NewDSNConnector(dsnStr string) (*Connector, error)
- func NewJWTAuthConnector(host, token string) *Connector
- func NewX509AuthConnector(host string, clientCert, clientKey []byte) *Connector
- func NewX509AuthConnectorByFiles(host, clientCertFile, clientKeyFile string) (*Connector, error)
- func (c Connector) ApplicationName() string
- func (c Connector) BufferSize() int
- func (c Connector) BulkSize() int
- func (c Connector) CESU8Decoder() func() transform.Transformer
- func (c Connector) CESU8Encoder() func() transform.Transformer
- func (c Connector) ClientCert() (clientCert, clientKey []byte)
- func (c *Connector) Connect(ctx context.Context) (driver.Conn, error)
- func (c Connector) DefaultSchema() string
- func (c Connector) Dfv() int
- func (c Connector) Dialer() dial.Dialer
- func (c *Connector) Driver() driver.Driver
- func (c Connector) FetchSize() int
- func (c Connector) Host() string
- func (c Connector) Legacy() bool
- func (c Connector) LobChunkSize() int
- func (c Connector) Locale() string
- func (c *Connector) NativeDriver() Driver
- func (c Connector) Password() string
- func (c Connector) PingInterval() time.Duration
- func (c Connector) RefreshClientCert() func() (clientCert, clientKey []byte, ok bool)
- func (c Connector) RefreshPassword() func() (password string, ok bool)
- func (c Connector) RefreshToken() func() (token string, ok bool)
- func (c Connector) SessionVariables() SessionVariables
- func (c Connector) SetApplicationName(name string)
- func (c Connector) SetBufferSize(bufferSize int)
- func (c Connector) SetBulkSize(bulkSize int)
- func (c Connector) SetCESU8Decoder(cesu8Decoder func() transform.Transformer)
- func (c Connector) SetCESU8Encoder(cesu8Encoder func() transform.Transformer)
- func (c Connector) SetDefaultSchema(schema string)
- func (c Connector) SetDfv(dfv int)
- func (c Connector) SetDialer(dialer dial.Dialer)
- func (c Connector) SetFetchSize(fetchSize int)
- func (c Connector) SetLegacy(b bool)
- func (c Connector) SetLobChunkSize(lobChunkSize int)
- func (c Connector) SetLocale(locale string)
- func (c Connector) SetPassword(password string)
- func (c Connector) SetPingInterval(d time.Duration)
- func (c Connector) SetRefreshClientCert(refreshClientCert func() (clientCert, clientKey []byte, ok bool))
- func (c Connector) SetRefreshPassword(refreshPassword func() (password string, ok bool))
- func (c Connector) SetRefreshToken(refreshToken func() (token string, ok bool))
- func (c Connector) SetSessionVariables(sessionVariables SessionVariables)
- func (c Connector) SetTCPKeepAlive(tcpKeepAlive time.Duration)
- func (c Connector) SetTLS(serverName string, insecureSkipVerify bool, rootCAFiles ...string) error
- func (c Connector) SetTLSConfig(tlsConfig *tls.Config)
- func (c Connector) SetTimeout(timeout time.Duration)
- func (c Connector) TCPKeepAlive() time.Duration
- func (c Connector) TLSConfig() *tls.Config
- func (c Connector) Timeout() time.Duration
- func (c Connector) Token() string
- func (c Connector) Username() string
- type DB
- type DBConnectInfo
- type DSN
- type Decimal
- type Driver
- type Error
- type Identifier
- type Lob
- type NullBytes
- type NullDecimal
- type NullLob
- type NullTimedeprecated
- type ParseError
- type SessionVariables
- type Sniffer
- type Stats
- type StatsHistogram
- type TLSPrms
- type Version
Examples ¶
Constants ¶
const ( LevelReadCommitted = "READ COMMITTED" LevelRepeatableRead = "REPEATABLE READ" LevelSerializable = "SERIALIZABLE" )
Transaction isolation levels supported by hdb.
const ( DSNDefaultSchema = "defaultSchema" // Database default schema. DSNTimeout = "timeout" // Driver side connection timeout in seconds. DSNPingInterval = "pingInterval" // Connection ping interval in seconds. )
DSN parameters. For parameter client locale see http://help.sap.com/hana/SAP_HANA_SQL_Command_Network_Protocol_Reference_en.pdf.
const ( DSNTLSRootCAFile = "TLSRootCAFile" // Path,- filename to root certificate(s). DSNTLSServerName = "TLSServerName" // ServerName to verify the hostname. DSNTLSInsecureSkipVerify = "TLSInsecureSkipVerify" // Controls whether a client verifies the server's certificate chain and host name. )
DSN TLS parameters. For more information please see https://golang.org/pkg/crypto/tls/#Config. For more flexibility in TLS configuration please see driver.Connector.
const ( HdbWarning = 0 HdbError = 1 HdbFatalError = 2 )
HDB error levels.
const DriverName = "hdb"
DriverName is the driver name to use with sql.Open for hdb databases.
const DriverVersion = "0.108.1"
DriverVersion is the version number of the hdb driver.
Variables ¶
var ( // NoFlush is to be used as parameter in bulk statements to delay execution. NoFlush = sql.Named(bulk, &noFlushTok) // Flush can be used as optional parameter in bulk statements but is not required to trigger execution. Flush = sql.Named(bulk, &flushTok) )
var ErrNestedQuery = errors.New("nested sql queries are not supported")
ErrNestedQuery is the error raised if a sql statement is executed before an "active" statement is closed. Example: execute sql statement before rows of previous select statement are closed.
var ErrNestedTransaction = errors.New("nested transactions are not supported")
ErrNestedTransaction is the error raised if a transaction is created within a transaction as this is not supported by hdb.
var ErrUnsupportedIsolationLevel = errors.New("unsupported isolation level")
ErrUnsupportedIsolationLevel is the error raised if a transaction is started with a not supported isolation level.
Functions ¶
This section is empty.
Types ¶
type Conn ¶ added in v0.103.0
type Conn interface { HDBVersion() *Version DatabaseName() string DBConnectInfo(ctx context.Context, databaseName string) (*DBConnectInfo, error) }
Conn enhances a connection with go-hdb specific connection functions.
type Connector ¶ added in v0.10.0
type Connector struct {
// contains filtered or unexported fields
}
A Connector represents a hdb driver in a fixed configuration. A Connector can be passed to sql.OpenDB (starting from go 1.10) allowing users to bypass a string based data source name.
func NewBasicAuthConnector ¶ added in v0.10.0
NewBasicAuthConnector creates a connector for basic authentication.
Example ¶
ExampleNewBasicAuthConnector shows how to open a database with the help of a connector using basic authentication.
package main import ( "database/sql" "log" "os" "strconv" "github.com/SAP/go-hdb/driver" ) func lookupTLS() (string, bool, string, bool) { const ( envServerName = "GOHDBTLSSERVERNAME" envInsecureSkipVerify = "GOHDBINSECURESKIPVERIFY" envRootCAFile = "GOHDBROOTCAFILE" ) set := false serverName, ok := os.LookupEnv(envServerName) if ok { set = true } insecureSkipVerify := false if b, ok := os.LookupEnv(envInsecureSkipVerify); ok { var err error if insecureSkipVerify, err = strconv.ParseBool(b); err != nil { log.Fatal(err) } set = true } rootCAFile, ok := os.LookupEnv(envRootCAFile) if ok { set = true } return serverName, insecureSkipVerify, rootCAFile, set } func main() { const ( envHost = "GOHDBHOST" envUsername = "GOHDBUSERNAME" envPassword = "GOHDBPASSWORD" ) host, ok := os.LookupEnv(envHost) if !ok { return } username, ok := os.LookupEnv(envUsername) if !ok { return } password, ok := os.LookupEnv(envPassword) if !ok { return } connector := driver.NewBasicAuthConnector(host, username, password) if serverName, insecureSkipVerify, rootCAFile, ok := lookupTLS(); ok { connector.SetTLS(serverName, insecureSkipVerify, rootCAFile) } db := sql.OpenDB(connector) defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
func NewConnector ¶ added in v0.103.0
func NewConnector() *Connector
NewConnector returns a new Connector instance with default values.
func NewDSNConnector ¶ added in v0.10.0
NewDSNConnector creates a connector from a data source name.
Example ¶
ExampleNewBasicAuthConnector shows how to open a database with the help of a connector using basic authentication.
package main import ( "database/sql" "log" "os" "github.com/SAP/go-hdb/driver" ) func main() { const ( envDSN = "GOHDBDSN" ) dsn, ok := os.LookupEnv(envDSN) if !ok { return } connector, err := driver.NewDSNConnector(dsn) if err != nil { log.Fatal(err) } db := sql.OpenDB(connector) defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
func NewJWTAuthConnector ¶ added in v0.107.0
NewJWTAuthConnector creates a connector for token (JWT) based authentication.
Example ¶
ExampleNewJWTAuthConnector shows how to open a database with the help of a connector using JWT authentication.
package main import ( "database/sql" "log" "os" "strconv" "github.com/SAP/go-hdb/driver" ) func lookupTLS() (string, bool, string, bool) { const ( envServerName = "GOHDBTLSSERVERNAME" envInsecureSkipVerify = "GOHDBINSECURESKIPVERIFY" envRootCAFile = "GOHDBROOTCAFILE" ) set := false serverName, ok := os.LookupEnv(envServerName) if ok { set = true } insecureSkipVerify := false if b, ok := os.LookupEnv(envInsecureSkipVerify); ok { var err error if insecureSkipVerify, err = strconv.ParseBool(b); err != nil { log.Fatal(err) } set = true } rootCAFile, ok := os.LookupEnv(envRootCAFile) if ok { set = true } return serverName, insecureSkipVerify, rootCAFile, set } func main() { const ( envHost = "GOHDBHOST" envToken = "GOHDBTOKEN" ) host, ok := os.LookupEnv(envHost) if !ok { return } token, ok := os.LookupEnv(envToken) if !ok { return } const invalidToken = "ey" connector := driver.NewJWTAuthConnector(host, invalidToken) if serverName, insecureSkipVerify, rootCAFile, ok := lookupTLS(); ok { connector.SetTLS(serverName, insecureSkipVerify, rootCAFile) } // in case JWT authentication fails provide a (new) valid token. connector.SetRefreshToken(func() (string, bool) { return token, true }) db := sql.OpenDB(connector) defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
func NewX509AuthConnector ¶ added in v0.107.0
NewX509AuthConnector creates a connector for X509 (client certificate) authentication.
func NewX509AuthConnectorByFiles ¶ added in v0.107.0
NewX509AuthConnectorByFiles creates a connector for X509 (client certificate) authentication based on client certificate and client key files.
Example ¶
ExampleNewX509AuthConnectorByFiles shows how to open a database with the help of a connector using x509 (client certificate) authentication and providing client certificate and client key by file.
package main import ( "database/sql" "log" "os" "strconv" "github.com/SAP/go-hdb/driver" ) func lookupTLS() (string, bool, string, bool) { const ( envServerName = "GOHDBTLSSERVERNAME" envInsecureSkipVerify = "GOHDBINSECURESKIPVERIFY" envRootCAFile = "GOHDBROOTCAFILE" ) set := false serverName, ok := os.LookupEnv(envServerName) if ok { set = true } insecureSkipVerify := false if b, ok := os.LookupEnv(envInsecureSkipVerify); ok { var err error if insecureSkipVerify, err = strconv.ParseBool(b); err != nil { log.Fatal(err) } set = true } rootCAFile, ok := os.LookupEnv(envRootCAFile) if ok { set = true } return serverName, insecureSkipVerify, rootCAFile, set } func main() { const ( envHost = "GOHDBHOST" envClientCertFile = "GOHDBCLIENTCERTFILE" envClientKeyFile = "GOHDBCLIENTKEYFILE" ) host, ok := os.LookupEnv(envHost) if !ok { return } clientCertFile, ok := os.LookupEnv(envClientCertFile) if !ok { return } clientKeyFile, ok := os.LookupEnv(envClientKeyFile) if !ok { return } connector, err := driver.NewX509AuthConnectorByFiles(host, clientCertFile, clientKeyFile) if err != nil { log.Fatal(err) } if serverName, insecureSkipVerify, rootCAFile, ok := lookupTLS(); ok { connector.SetTLS(serverName, insecureSkipVerify, rootCAFile) } db := sql.OpenDB(connector) defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
func (Connector) ApplicationName ¶ added in v0.103.0
func (c Connector) ApplicationName() string
ApplicationName returns the locale of the connector.
func (Connector) BufferSize ¶ added in v0.99.0
func (c Connector) BufferSize() int
BufferSize returns the bufferSize of the connector.
func (Connector) BulkSize ¶ added in v0.99.0
func (c Connector) BulkSize() int
BulkSize returns the bulkSize of the connector.
func (Connector) CESU8Decoder ¶ added in v0.105.1
func (c Connector) CESU8Decoder() func() transform.Transformer
CESU8Decoder returns the CESU-8 decoder of the connector.
func (Connector) CESU8Encoder ¶ added in v0.105.1
func (c Connector) CESU8Encoder() func() transform.Transformer
CESU8Encoder returns the CESU-8 encoder of the connector.
func (Connector) ClientCert ¶ added in v0.107.0
func (c Connector) ClientCert() (clientCert, clientKey []byte)
ClientCert returns the X509 authentication client certificate and key of the connector.
func (*Connector) Connect ¶ added in v0.10.0
Connect implements the database/sql/driver/Connector interface.
func (Connector) DefaultSchema ¶ added in v0.99.0
func (c Connector) DefaultSchema() string
DefaultSchema returns the database default schema of the connector.
func (Connector) Dfv ¶ added in v0.99.0
func (c Connector) Dfv() int
Dfv returns the client data format version of the connector.
func (*Connector) Driver ¶ added in v0.10.0
Driver implements the database/sql/driver/Connector interface.
func (Connector) FetchSize ¶ added in v0.10.0
func (c Connector) FetchSize() int
FetchSize returns the fetchSize of the connector.
func (Connector) Host ¶ added in v0.10.0
func (c Connector) Host() string
Host returns the host of the connector.
func (Connector) Legacy ¶ added in v0.99.0
func (c Connector) Legacy() bool
Legacy returns the connector legacy flag.
func (Connector) LobChunkSize ¶ added in v0.99.0
func (c Connector) LobChunkSize() int
LobChunkSize returns the lobChunkSize of the connector.
func (Connector) Locale ¶ added in v0.10.0
func (c Connector) Locale() string
Locale returns the locale of the connector.
func (*Connector) NativeDriver ¶ added in v0.107.0
NativeDriver returns the concrete underlying Driver of the Connector.
func (Connector) Password ¶ added in v0.10.0
func (c Connector) Password() string
Password returns the basic authentication password of the connector.
func (Connector) PingInterval ¶ added in v0.100.9
PingInterval returns the connection ping interval of the connector.
func (Connector) RefreshClientCert ¶ added in v0.107.0
RefreshClientCert returns the callback function for X509 authentication client certificate and key refresh.
func (Connector) RefreshPassword ¶ added in v0.107.0
RefreshPassword returns the callback function for basic authentication password refresh.
func (Connector) RefreshToken ¶ added in v0.107.0
RefreshToken returns the callback function for JWT authentication token refresh.
func (Connector) SessionVariables ¶ added in v0.14.0
func (c Connector) SessionVariables() SessionVariables
SessionVariables returns the session variables stored in connector.
func (Connector) SetApplicationName ¶ added in v0.103.0
func (c Connector) SetApplicationName(name string)
SetApplicationName sets the application name of the connector.
func (Connector) SetBufferSize ¶ added in v0.103.0
func (c Connector) SetBufferSize(bufferSize int)
SetBufferSize sets the bufferSize of the connector.
func (Connector) SetBulkSize ¶ added in v0.99.0
func (c Connector) SetBulkSize(bulkSize int)
SetBulkSize sets the bulkSize of the connector.
func (Connector) SetCESU8Decoder ¶ added in v0.105.1
func (c Connector) SetCESU8Decoder(cesu8Decoder func() transform.Transformer)
SetCESU8Decoder sets the CESU-8 decoder of the connector.
func (Connector) SetCESU8Encoder ¶ added in v0.105.1
func (c Connector) SetCESU8Encoder(cesu8Encoder func() transform.Transformer)
SetCESU8Encoder sets the CESU-8 encoder of the connector.
func (Connector) SetDefaultSchema ¶ added in v0.99.0
func (c Connector) SetDefaultSchema(schema string)
SetDefaultSchema sets the database default schema of the connector.
func (Connector) SetDfv ¶ added in v0.99.0
func (c Connector) SetDfv(dfv int)
SetDfv sets the client data format version of the connector.
func (Connector) SetFetchSize ¶ added in v0.10.0
func (c Connector) SetFetchSize(fetchSize int)
SetFetchSize sets the fetchSize of the connector.
For more information please see DSNFetchSize.
func (Connector) SetLegacy ¶ added in v0.99.0
func (c Connector) SetLegacy(b bool)
SetLegacy sets the connector legacy flag.
func (Connector) SetLobChunkSize ¶ added in v0.105.1
func (c Connector) SetLobChunkSize(lobChunkSize int)
SetLobChunkSize sets the lobChunkSize of the connector.
func (Connector) SetLocale ¶ added in v0.10.0
func (c Connector) SetLocale(locale string)
SetLocale sets the locale of the connector.
For more information please see DSNLocale.
func (Connector) SetPassword ¶ added in v0.108.0
func (c Connector) SetPassword(password string)
SetPassword sets the basic authentication password of the connector.
func (Connector) SetPingInterval ¶ added in v0.100.9
SetPingInterval sets the connection ping interval value of the connector.
If the ping interval is greater than zero, the driver pings all open connections (active or idle in connection pool) periodically. Parameter d defines the time between the pings in milliseconds.
func (Connector) SetRefreshClientCert ¶ added in v0.107.0
func (c Connector) SetRefreshClientCert(refreshClientCert func() (clientCert, clientKey []byte, ok bool))
SetRefreshClientCert sets the callback function for X509 authentication client certificate and key refresh.
func (Connector) SetRefreshPassword ¶ added in v0.107.0
SetRefreshPassword sets the callback function for basic authentication password refresh.
func (Connector) SetRefreshToken ¶ added in v0.107.0
SetRefreshToken sets the callback function for JWT authentication token refresh.
func (Connector) SetSessionVariables ¶ added in v0.14.0
func (c Connector) SetSessionVariables(sessionVariables SessionVariables)
SetSessionVariables sets the session varibles of the connector.
func (Connector) SetTCPKeepAlive ¶ added in v0.100.8
SetTCPKeepAlive sets the tcp keep-alive value of the connector.
For more information please see net.Dialer structure.
func (Connector) SetTLS ¶ added in v0.107.0
SetTLS sets the TLS configuration of the connector with given parameters. An existing connector TLS configuration is replaced.
func (Connector) SetTLSConfig ¶ added in v0.11.0
SetTLSConfig sets the TLS configuration of the connector.
func (Connector) SetTimeout ¶ added in v0.10.0
SetTimeout sets the timeout of the connector.
For more information please see DSNTimeout.
func (Connector) TCPKeepAlive ¶ added in v0.100.8
TCPKeepAlive returns the tcp keep-alive value of the connector.
func (Connector) TLSConfig ¶ added in v0.11.0
TLSConfig returns the TLS configuration of the connector.
type DB ¶ added in v0.108.0
type DB struct { // The embedded sql.DB instance. Please use only the methods of the wrapper (driver.DB). // The field is exported to support use cases where a sql.DB object is requested, but please // use with care as some of the sql.DB methods (e.g. Close) are redefined in driver.DB. *sql.DB // contains filtered or unexported fields }
DB represents a driver database and can be used as a replacement for sql.DB. It provides all of the sql.DB methods plus additional methods only available for driver.DB.
Example ¶
ExampleDB shows hot to print extended database statistics with the help of function driver.OpenDB and a driver.DB object.
package main import ( "database/sql" "log" "github.com/SAP/go-hdb/driver" ) func main() { // print default sql database statistics. db1 := sql.OpenDB(driver.DefaultTestConnector()) log.Printf("waitDuration: %d", db1.Stats().WaitDuration) // print field waitDuration of default database statistics. db1.Close() // print extended go-hdb driver db statistics. db2 := driver.OpenDB(driver.DefaultTestConnector()) log.Printf("waitDuration: %d", db2.Stats().WaitDuration) // print field waitDuration of default database statistics. log.Printf("bytesWritten: %d", db2.ExStats().WrittenBytes) // print field bytesWritten of extended driver database statistics. db2.Close() }
Output:
func OpenDB ¶ added in v0.108.0
OpenDB opens and returns a database. It also calls the OpenDB method of the sql package and stores an embedded *sql.DB object.
type DBConnectInfo ¶ added in v0.107.3
DBConnectInfo defines the connection information attributes returned by hdb.
func (*DBConnectInfo) String ¶ added in v0.107.3
func (ci *DBConnectInfo) String() string
type DSN ¶
type DSN struct {
// contains filtered or unexported fields
}
A DSN represents a parsed DSN string. A DSN string is an URL string with the following format
"hdb://<username>:<password>@<host address>:<port number>"
and optional query parameters (see DSN query parameters and DSN query default values).
Example:
"hdb://myuser:mypassword@localhost:30015?timeout=60"
Examples TLS connection:
"hdb://myuser:mypassword@localhost:39013?TLSRootCAFile=trust.pem" "hdb://myuser:mypassword@localhost:39013?TLSRootCAFile=trust.pem&TLSServerName=hostname" "hdb://myuser:mypassword@localhost:39013?TLSInsecureSkipVerify"
Example ¶
ExampleDSN shows how to construct a DSN (data source name) as url.
// SPDX-FileCopyrightText: 2014-2022 SAP SE // // SPDX-License-Identifier: Apache-2.0 package main import ( "database/sql" "log" "net/url" "github.com/SAP/go-hdb/driver" ) // dsn creates data source name with the help of the net/url package. func dsn() string { dsn := &url.URL{ Scheme: driver.DriverName, User: url.UserPassword("user", "password"), Host: "host:port", } return dsn.String() } // ExampleDSN shows how to construct a DSN (data source name) as url. func main() { db, err := sql.Open(driver.DriverName, dsn()) if err != nil { log.Fatal(err) } defer db.Close() if err := db.Ping(); err != nil { log.Fatal(err) } }
Output:
type Decimal ¶
A Decimal is the driver representation of a database decimal field value as big.Rat.
Example ¶
ExampleDecimal creates a table with a single decimal attribute, insert a record into it and select the entry afterwards. This demonstrates the usage of the type Decimal to write and scan decimal database attributes.
package main import ( "database/sql" "fmt" "log" "math/big" "github.com/SAP/go-hdb/driver" ) func main() { db := sql.OpenDB(driver.DefaultTestConnector()) defer db.Close() tableName := driver.RandomIdentifier("table_") if _, err := db.Exec(fmt.Sprintf("create table %s (x decimal)", tableName)); err != nil { // Create table with decimal attribute. log.Fatal(err) } // Decimal values are represented in Go as big.Rat. in := (*driver.Decimal)(big.NewRat(1, 1)) // Create *big.Rat and cast to Decimal. if _, err := db.Exec(fmt.Sprintf("insert into %s values(?)", tableName), in); err != nil { // Insert record. log.Fatal(err) } var out driver.Decimal // Declare scan variable. if err := db.QueryRow(fmt.Sprintf("select * from %s", tableName)).Scan(&out); err != nil { log.Fatal(err) } fmt.Printf("Decimal value: %s", (*big.Rat)(&out).String()) // Cast scan variable to *big.Rat to use *big.Rat methods. }
Output: Decimal value: 1/1
type Driver ¶ added in v0.103.0
type Driver interface { Name() string // Name returns the driver name. Version() string // Version returns the driver version. Stats() *Stats // Stats returns aggregated driver statistics. }
Driver enhances a connection with go-hdb specific connection functions.
type Error ¶
type Error interface { Error() string // Implements the golang error interface. NumError() int // NumError returns the number of errors. SetIdx(idx int) // Sets the error index in case number of errors are greater 1 in the range of 0 <= index < NumError(). StmtNo() int // Returns the statement number of the error in multi statement contexts (e.g. bulk insert). Code() int // Code return the database error code. Position() int // Position returns the start position of erroneous sql statements sent to the database server. Level() int // Level return one of the database server predefined error levels. Text() string // Text return the error description sent from database server. IsWarning() bool // IsWarning returns true if the HDB error level equals 0. IsError() bool // IsError returns true if the HDB error level equals 1. IsFatal() bool // IsFatal returns true if the HDB error level equals 2. }
Error represents errors send by the database server.
Example ¶
//go:build !unit // +build !unit // SPDX-FileCopyrightText: 2014-2022 SAP SE // // SPDX-License-Identifier: Apache-2.0 package main import ( "database/sql" "errors" "fmt" "log" "github.com/SAP/go-hdb/driver" ) const ( errCodeInvalidTableName = 259 ) func main() { db := sql.OpenDB(driver.DefaultTestConnector()) defer db.Close() invalidTableName := driver.RandomIdentifier("table_") stmt, err := db.Query(fmt.Sprintf("select * from %s", invalidTableName)) if err == nil { defer stmt.Close() } var dbError driver.Error if err != nil { // Check if error is driver.Error. if errors.As(err, &dbError) { switch dbError.Code() { case errCodeInvalidTableName: fmt.Print("invalid table name") default: log.Fatalf("code %d text %s", dbError.Code(), dbError.Text()) } } } }
Output: invalid table name
type Identifier ¶
type Identifier string
Identifier in hdb SQL statements like schema or table name.
func RandomIdentifier ¶
func RandomIdentifier(prefix string) Identifier
RandomIdentifier returns a random Identifier prefixed by the prefix parameter. This function is used to generate database objects with random names for test and example code.
func (Identifier) String ¶
func (i Identifier) String() string
type Lob ¶
type Lob struct {
// contains filtered or unexported fields
}
A Lob is the driver representation of a database large object field. A Lob object uses an io.Reader object as source for writing content to a database lob field. A Lob object uses an io.Writer object as destination for reading content from a database lob field. A Lob can be created by contructor method NewLob with io.Reader and io.Writer as parameters or created by new, setting io.Reader and io.Writer by SetReader and SetWriter methods.
Example (Pipe) ¶
ExampleLobPipe: - inserts data read from a file into a database large object field - and retrieves the data afterwards An io.Pipe is used to insert and retrieve Lob data in chunks.
package main import ( "bufio" "database/sql" "fmt" "io" "log" "os" "sync" "github.com/SAP/go-hdb/driver" ) func main() { // Open test file. file, err := os.Open("example_lob_test.go") if err != nil { log.Fatal(err) } defer file.Close() // Open Test database. db := sql.OpenDB(driver.DefaultTestConnector()) defer db.Close() tx, err := db.Begin() // Start Transaction to avoid database error: SQL Error 596 - LOB streaming is not permitted in auto-commit mode. if err != nil { log.Fatal(err) } // Create table. table := driver.RandomIdentifier("fileLob") if _, err := tx.Exec(fmt.Sprintf("create table %s (file nclob)", table)); err != nil { log.Fatalf("create table failed: %s", err) } stmt, err := tx.Prepare(fmt.Sprintf("insert into %s values (?)", table)) if err != nil { log.Fatal(err) } lob := &driver.Lob{} // Lob field. pipeReader, pipeWriter := io.Pipe() // Create pipe for writing Lob. lob.SetReader(pipeReader) // Use PipeReader as reader for Lob. // Use sync.WaitGroup to wait for go-routines to be ended. wg := new(sync.WaitGroup) wg.Add(1) // Select statement. // Start sql insert in own go-routine. // The go-routine is going to be ended when the data write via the PipeWriter is finalized. go func() { if _, err := stmt.Exec(lob); err != nil { log.Fatal(err) } fmt.Println("exec finalized") wg.Done() }() // Read file line by line and write data to pipe. scanner := bufio.NewScanner(file) for scanner.Scan() { if _, err := pipeWriter.Write(scanner.Bytes()); err != nil { log.Fatal(err) } if _, err := pipeWriter.Write([]byte{'\n'}); err != nil { // Write nl which was stripped off by scanner. log.Fatal(err) } } if err := scanner.Err(); err != nil { log.Fatal(err) } // Close pipeWriter (end insert into db). pipeWriter.Close() // Wait until exec go-routine is ended. wg.Wait() stmt.Close() if err := tx.Commit(); err != nil { log.Fatal(err) } pipeReader, pipeWriter = io.Pipe() // Create pipe for reading Lob. lob.SetWriter(pipeWriter) // Use PipeWriter as writer for Lob. wg.Add(1) // Exec statement. // Start sql select in own go-routine. // The go-routine is going to be ended when the data read via the PipeReader is finalized. go func() { if err := db.QueryRow(fmt.Sprintf("select * from %s", table)).Scan(lob); err != nil { log.Fatal(err) } fmt.Println("scan finalized") wg.Done() }() // Read Lob line by line via bufio.Scanner. scanner = bufio.NewScanner(pipeReader) for scanner.Scan() { // Do something with scan result. } if err := scanner.Err(); err != nil { log.Fatal(err) } pipeReader.Close() // Wait until select go-routine is ended. wg.Wait() }
Output: exec finalized scan finalized
Example (Read) ¶
ExampleLobRead reads data from a largs data object database field into a bytes.Buffer. Precondition: the test database table with one field of type BLOB, CLOB or NCLOB must exist. For illustrative purposes we assume, that the database table has exactly one record, so that we can use db.QueryRow.
package main import ( "bytes" "database/sql" "log" "github.com/SAP/go-hdb/driver" ) func main() { b := new(bytes.Buffer) db, err := sql.Open("hdb", "hdb://user:password@host:port") if err != nil { log.Fatal(err) } defer db.Close() lob := new(driver.Lob) lob.SetWriter(b) // SetWriter sets the io.Writer object, to which the database content of the lob field is written. if err := db.QueryRow("select * from test").Scan(lob); err != nil { log.Fatal(err) } }
Output:
Example (Write) ¶
ExampleLobWrite inserts data read from a file into a database large object field. Precondition: the test database table with one field of type BLOB, CLOB or NCLOB and the test.txt file in the working directory must exist. Lob fields cannot be written in hdb auto commit mode - therefore the insert has to be executed within a transaction.
package main import ( "database/sql" "log" "os" "github.com/SAP/go-hdb/driver" ) func main() { file, err := os.Open("test.txt") // Open file. if err != nil { log.Fatal(err) } defer file.Close() db, err := sql.Open("hdb", "hdb://user:password@host:port") if err != nil { log.Fatal(err) } defer db.Close() tx, err := db.Begin() // Start Transaction to avoid database error: SQL Error 596 - LOB streaming is not permitted in auto-commit mode. if err != nil { log.Fatal(err) } stmt, err := tx.Prepare("insert into test values(?)") if err != nil { log.Fatal(err) } lob := new(driver.Lob) lob.SetReader(file) // SetReader sets the io.Reader object, which content is written to the database lob field. if _, err := stmt.Exec(lob); err != nil { log.Fatal(err) } stmt.Close() if err := tx.Commit(); err != nil { log.Fatal(err) } }
Output:
func NewLob ¶
NewLob creates a new Lob instance with the io.Reader and io.Writer given as parameters.
func (*Lob) SetReader ¶
SetReader sets the io.Reader source for a lob field to be written to database and return *Lob, to enable simple call chaining.
func (*Lob) SetWriter ¶
SetWriter sets the io.Writer destination for a lob field to be read from database and return *Lob, to enable simple call chaining.
type NullBytes ¶ added in v0.9.1
NullBytes represents an []byte that may be null. NullBytes implements the Scanner interface so it can be used as a scan destination, similar to NullString.
type NullDecimal ¶
NullDecimal represents an Decimal that may be null. NullDecimal implements the Scanner interface so it can be used as a scan destination, similar to NullString.
func (*NullDecimal) Scan ¶
func (n *NullDecimal) Scan(value interface{}) error
Scan implements the Scanner interface.
type NullLob ¶ added in v0.11.1
NullLob represents an Lob that may be null. NullLob implements the Scanner interface so it can be used as a scan destination, similar to NullString.
type ParseError ¶ added in v0.107.0
type ParseError struct {
// contains filtered or unexported fields
}
ParseError is the error returned in case DSN is invalid.
func (ParseError) Cause ¶ added in v0.107.0
func (e ParseError) Cause() error
Cause returns the cause of the error.
func (ParseError) Error ¶ added in v0.107.0
func (e ParseError) Error() string
func (ParseError) Unwrap ¶ added in v0.107.0
func (e ParseError) Unwrap() error
Unwrap returns the nested error.
type SessionVariables ¶ added in v0.14.0
SessionVariables maps session variables to their values. All defined session variables will be set once after a database connection is opened.
type Sniffer ¶ added in v0.107.3
type Sniffer struct {
// contains filtered or unexported fields
}
A Sniffer is a simple proxy for logging hdb protocol requests and responses.
func NewSniffer ¶ added in v0.107.3
NewSniffer creates a new sniffer instance. The conn parameter is the net.Conn connection, where the Sniffer is listening for hdb protocol calls. The dbAddr is the hdb host port address in "host:port" format.
type Stats ¶ added in v0.103.0
type Stats struct { // Gauges OpenConnections int // The number of current established driver connections. OpenTransactions int // The number of current open driver transactions. OpenStatements int // The number of current open driver database statements. // Counters ReadBytes uint64 // Total bytes read by client connection. WrittenBytes uint64 // Total bytes written by client connection. // Time histograms (Sum and upper bounds in milliseconds) ReadTime *StatsHistogram // Time spent on reading from connection. WriteTime *StatsHistogram // Time spent on writing to connection. AuthTime *StatsHistogram // Time spent on authentication. SQLTimes map[string]*StatsHistogram // Time spent on different SQL statements. }
Stats contains driver statistics.
type StatsHistogram ¶ added in v0.107.4
type StatsHistogram struct { // Count holds the number of measurements Count uint64 // Sum holds the sum of the measurements. Sum float64 // Buckets contains the count of measurements belonging to a bucket where the // value of the measurement is less or equal the bucket map key. Buckets map[float64]uint64 }
StatsHistogram represents statistic data in a histogram structure.
type Version ¶ added in v0.107.3
type Version struct {
// contains filtered or unexported fields
}
Version is representing a hdb version.
func (*Version) BuildID ¶ added in v0.107.3
BuildID returns the build id field of a HDBVersionNumber.
func (*Version) Revision ¶ added in v0.107.3
Revision returns the revision field of a HDBVersionNumber.
Source Files ¶
- atomicBool1.19.go
- authattrs.go
- bytes.go
- connattrs.go
- connection.go
- connector.go
- convert.go
- dbconnectinfo.go
- decimal.go
- deprecated.go
- doc.go
- driver.go
- dsn.go
- error.go
- go1.18.go
- identifier.go
- lob.go
- log.go
- metrics.go
- querydescr.go
- queryresultcache.go
- rand.go
- result.go
- sniffer.go
- stats.go
- statscfg.go
- version.go
Directories ¶
Path | Synopsis |
---|---|
Package dial provides types to implement go-hdb custom dialers.
|
Package dial provides types to implement go-hdb custom dialers. |
Package hdb defines hdb specific data structures used by the driver (deprecated).
|
Package hdb defines hdb specific data structures used by the driver (deprecated). |
internal
|
|
errors
Package errors defines errors used in different driver packages.
|
Package errors defines errors used in different driver packages. |
logflag
Package logflag provides a boolean flag to use with log enablement.
|
Package logflag provides a boolean flag to use with log enablement. |
protocol
Package protocol implements the hdb command network protocol.
|
Package protocol implements the hdb command network protocol. |
protocol/auth
Package auth provides authentication methods.
|
Package auth provides authentication methods. |
protocol/encoding
Package encoding implements hdb field type en,- and decodings.
|
Package encoding implements hdb field type en,- and decodings. |
protocol/julian
Package julian provided julian time conversion functions.
|
Package julian provided julian time conversion functions. |
protocol/scanner
Package scanner implements a HANA SQL query scanner.
|
Package scanner implements a HANA SQL query scanner. |
prometheus
|
|
collectors
Package collectors provides prometheus collectors for driver and extended database statistics.
|
Package collectors provides prometheus collectors for driver and extended database statistics. |
Package spatial implements geo spatial types and functions.
|
Package spatial implements geo spatial types and functions. |
Package sqltrace implements driver sql trace functions.
|
Package sqltrace implements driver sql trace functions. |
unicode
|
|
cesu8
Package cesu8 implements functions and constants to support text encoded in CESU-8.
|
Package cesu8 implements functions and constants to support text encoded in CESU-8. |