cgo-ase
is a driver for the database/sql
package
of Go (golang) to provide access to SAP ASE instances.
It is delivered as Go module.
SAP ASE is the shorthand for SAP Adaptive Server Enterprise, a relational model database server originally known as Sybase SQL Server.
cgo enables Go to call C code and to link against shared objects. A pure go implementation can be found here.
The cgo
driver requires the shared objects from either the ASE itself
or Client-Library to compile.
The required shared objects from ASE can be found in the installation
path of the ASE under OCS-16_0/lib
, where 16_0
is the version of
your ASE installation.
After installing the Client-Library SDK the
shared objects can be found in the folder lib
at the chosen
installation path.
The headers are provided in the includes
folder.
Aside from the shared object the cgo driver has no special requirements
other than Go standard library and the third party modules listed in
go.mod
, e.g. github.com/SAP/go-dblib
.
The packages in this repo can be go get
and imported as usual, e.g.:
go get github.com/SAP/cgo-ase
For specifics on how to use database/sql
please see the
documentation.
Example code:
package main
import (
"database/sql"
_ "github.com/SAP/cgo-ase"
)
func main() {
db, err := sql.Open("ase", "ase://user:pass@host:port/")
if err != nil {
log.Printf("Failed to open database: %v", err)
return
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Printf("Failed to ping database: %v", err)
return
}
}
/path/to/OCS
is the path to your Client-Library SDK installation.
/lib
is the folder inside of the SDK installation containing the
shared objects required for the cgo driver.
CGO_LDFLAGS="-L/path/to/OCS/lib" go build -o cgoase ./cmd/cgoase/
LD_LIBRARY_PATH="/path/to/OCS/lib" ./cgoase
More examples can be found in the folder examples
.
Integration tests are available and can be run using go test --tags=integration
and
go test ./examples/... --tags=integration
.
These require the following environment variables to be set:
ASE_USERSTOREKEY
ASE_HOST
ASE_PORT
ASE_USER
ASE_PASS
The integration tests will create new databases for each connection type to run tests against. After the tests are finished the created databases will be removed.
The configuration is handled through either a data source name (DSN) in one of two forms or through a configuration struct passed to a connector.
All of these support additional properties which can tweak the connection, configuration options in Client-Library or the drivers themselves.
The URI DSN is a common URI like ase://user:pass@host:port/?prop1=val1&prop2=val2
.
DSNs in this form are parsed using url.Parse
.
The simple DSN is a key/value string: username=user password=pass host=hostname port=4901
Values with spaces must be quoted using single or double quotes.
Each member of dblib.dsn.DsnInfo
can be set using any of their
possible json tags. E.g. .Host
will receive the values from the keys
host
and hostname
.
Additional properties are set as key/value pairs as well: ... prop1=val1 prop2=val2
. If the parser doesn't recognize a string as
a json tag it assumes that the key/value pair is a property and its
value.
Similar to the URI DSN those property/value pairs are purely additive. Any property that only recognizes a single argument (e.g. a boolean) will only honour the last given value for a property.
As an alternative to the string DSN ase.NewConnector
accept a dsn.DsnInfo
directly and return a driver.Connector
, which can be passed to sql.OpenDB
:
package main
import (
"database/sql"
"github.com/SAP/cgo-ase"
)
func main() {
info := ase.NewInfo()
info.Host = "hostname"
info.Port = "4901"
info.Username = "user"
info.Password = "pass"
connector, err := ase.NewConnector(info)
if err != nil {
log.Printf("Failed to create connector: %v", err)
return
}
db, err := sql.OpenDB(connector)
if err != nil {
log.Printf("Failed to open database: %v", err)
return
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Printf("Failed to ping ASE: %v", err)
}
}
Recognized values: yes
or any string
When set to yes
all client messages will be printed to stderr.
Please note that this is a debug property - for logging you should
register your own message handler with the GlobalClientMessageBroker
.
When set to any other string the callback will not bet set.
Recognized values: yes
or any string
When set to yes
all server messages will be printed to stderr.
Please note that this is a debug property - for logging you should
register your own message handler with the GlobalServerMessageBroker
.
When set to any other string the callback will not be set.
Regarding the limitations of prepared statements/dynamic SQL please see the Client-Library documentation.
Currently the following data types are not supported:
- Timestamp
- Univarchar
Due to the limitations of the Client-Library it is not possible to support null types.
Additionally columns of the following data types must be nullable:
- Image
- Binary
The list of known issues is available here.
Feel free to open issues for feature requests, bugs or general feedback here.
Any help to improve this package is highly appreciated.
For details on how to contribute please see the contributing file.
Copyright (c) 2019-2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache License 2.0 except as noted otherwise in the LICENSE file.