Technical Articles
go-ase: an open source ASE database driver for the Go programming language
Attention:
This blog post is outdated. Meanwhile there are two Go SQL drivers available for SAP ASE:
- https://github.com/SAP/go-ase This is the pure go driver directly connecting to the ASE using the TDS protocol.
- https://github.com/SAP/cgo-ase This is the cgo driver which wraps the existing shared libraries to connect to an ASE.
Please don’t hesitate to raise issue at https://github.com/SAP/go-ase/issues and https://github.com/SAP/cgo-ase/issues.
You will find similar examples like the one of this blog post in the documentation of the above repositories.
Let’s go
The programming language Go by Google is getting more and more popular. Young talents learn the language and want to leverage powerful features like its concurrency model.
Within SAP IT we also love Go and want to use it for database tools around HANA and ASE. Up to now there was no SQL package driver available for ASE.
The new package go-ase is meant to fill this gap. So far it uses cgo to connect to the database using the shared libraries. However, a pure Go driver is planned.
Let’s go through a small example how you can use the package to write your own Go program.
Requirements
To keep our example simple, we are going to use a SLES Linux server with a running ASE for Business Suite. To be able to compile a Go program you must have Go installed. Let’s install the latest version 1.12.5 released on May 5th.
# as root
wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.12.5.linux-amd64.tar.gz
As the package uses cgo we also need gcc in place.
zypper in gcc
Write the Program
For simplicity we write our program as the ASE for Business Suite user syb<sid>. For this create a new directory with a file main.go.
# as syb<sid>
setenv PATH "$PATH":/usr/local/go/bin
mkdir myGoProgram
cd myGoProgram
vi main.go
Fill the file main.go with the following Go code and save it.
package main
import (
"database/sql"
"flag"
"fmt"
"os"
_ "github.com/SAP/go-ase/cgo"
"github.com/SAP/go-ase/libase/libdsn"
)
func main() {
var login string
flag.StringVar(&login, "login", "sa", "login you want to examine")
flag.Parse()
dsn := libdsn.NewDsnInfoFromEnv("")
db, err := sql.Open("ase", dsn.AsSimple())
if err != nil {
fmt.Fprintf(os.Stderr, "Could not open database: %v", err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Fprintf(os.Stderr, "Could not ping database: %v", err)
return
}
rows, err := db.Query("select dbname from master..syslogins where name = '?'", login)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not query database: %v", err)
return
}
defer rows.Close()
var dbname string
for rows.Next() {
err := rows.Scan(&dbname)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not scan rows: %v", err)
return
}
fmt.Printf("Database of %s is %s.\n", login, dbname)
}
return
err = rows.Err()
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
}
Also, let’s make it a Go module.
go mod init myGoProgram
go mod tidy
This downloads all the necessary dependencies to ~/go and creates a go.mod and a go.sum for you.
Compile the Program
Now compile the program.
setenv CGO_LDFLAGS "-L$SYBASE/OCS-16_0/lib -lsybct_r64 -lsybcs_r64"
go build
If the above fails, then please check if $SYBASE/OCS-16_0/lib has to be adjusted in your case.
Run the Program
As the program connects to your database you have to provide connections details. The above program uses environment variables.
setenv ASE_HOST '<host>'
setenv ASE_PORT 4901
setenv ASE_USER sapsa
setenv ASE_PASS '<pass>'
Then run your program:
./myGoProgram
Database of sa is master.
This prints the database of login sa. You can also specify different logins:
./myGoProgram -login sapsso
Database of sapsso is master.
./myGoProgram -login sapsa
Database of sapsa is saptools.
You can also specify an aseuserstore:
setenv ASE_USERSTOREKEY SAPSA
Again, run your program:
./myGoProgram
Database of sa is master.
What’s next?
You can use go-ase with your own Go programs to connect to and work with ASE databases. Next to the existing cgo package a pure Go implementation is planned. Please visit https://github.com/SAP/go-ase for more details about go-ase.
Credits
Many thanks to Nelo-T. Wallus for making this possible.
I'm a Go newbie. Very interesting. For other Go newbies, see http://go-database-sql.org/index.html
Took me a few minutes to figure out libdsn.NewDsnInfoFromEnv (using code from https://github.com/SAP/go-ase/blob/master/libase/libdsn/dsn.go) Gets ASE_* environment variables specified in the "Run the Program" section of this page, fine.
Looking at Go database drivers at golang.org/s/sqldrivers, I see:
Sybase ASE (pure go): https://github.com/thda/tds
Is that your competition? Do they work the same as your drivers? (and github.com/SAP/go-ase isn't listed there)
Also, will a native Go db driver be slower than calling C libraries when processing large volumes of data?
Thanks
Ben
Dear Ben,
thanks for your interest!
The environment options are documented at https://godoc.org/github.com/SAP/go-ase/libase/libdsn#NewDsnInfoFromEnv. The cgo implementation is especially capable to leverage ase userstore keys next to user/password credentials.
Some minutes ago we announced the package on golang-sql and mentioned it on https://github.com/golang/go/wiki/SQLDrivers.
We are in contact with thda and the authors of the tds package and look forward to working together.
As soon as we have more data and benchmarks we may be able to answer the performance question. If you have any experiences please let us know.
Thanks
Chris and Nelo