Firebolt GO driver is an implementation of database/sql/driver
.
go get github.com/firebolt-db/firebolt-go-sdk
All information for the connection should be specified using the DSN string. The firebolt dsn string has the following format:
firebolt://[/database]?account_name=account_name&client_id=client_id&client_secret=client_secret[&engine=engine]
- client_id - credentials client id.
- client_secret - credentials client secret.
- account_name - the name of Firebolt account to log in to.
- database - (optional) the name of the database to connect to.
- engine - (optional) the name of the engine to run SQL on.
Here is an example of establishing a connection and executing a simple select query. For it to run successfully, you have to specify your credentials, and have a default engine up and running.
package main
import (
"database/sql"
"fmt"
// we need to import firebolt-go-sdk in order to register the driver
_ "github.com/firebolt-db/firebolt-go-sdk"
)
func main() {
// set your Firebolt credentials to construct a dsn string
clientId := ""
clientSecret := ""
accountName := ""
databaseName := ""
dsn := fmt.Sprintf("firebolt:///%s?account_name=%s&client_id=%s&client_secret=%s", databaseName, accountName, clientId, clientSecret)
// open a Firebolt connection
db, err := sql.Open("firebolt", dsn)
if err != nil {
fmt.Printf("error during opening a driver: %v", err)
}
// create a table
_, err = db.Query("CREATE TABLE test_table(id INT, value TEXT)")
if err != nil {
fmt.Printf("error during select query: %v", err)
}
// execute a parametrized insert (only ? placeholders are supported)
_, err = db.Query("INSERT INTO test_table VALUES (?, ?)", 1, "my value")
if err != nil {
fmt.Printf("error during select query: %v", err)
}
// execute a simple select query
rows, err := db.Query("SELECT id FROM test_table")
if err != nil {
fmt.Printf("error during select query: %v", err)
}
// iterate over the result
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("error during rows.Close(): %v\n", err)
}
}()
for rows.Next() {
var id int
if err := rows.Scan(&id); err != nil {
fmt.Printf("error during scan: %v", err)
}
fmt.Println(id)
}
if err := rows.Err(); err != nil {
fmt.Printf("error during rows iteration: %v\n", err)
}
}
In order to stream the query result (and not store it in memory fully), you need to pass a special context with streaming enabled.
Warning: If you enable streaming the result, the query execution might finish successfully, but the actual error might be returned during the iteration over the rows.
Here is an example of how to do it:
package main
import (
"context"
"database/sql"
"fmt"
// we need to import firebolt-go-sdk in order to register the driver
_ "github.com/firebolt-db/firebolt-go-sdk"
fireboltContext "github.com/firebolt-db/firebolt-go-sdk/context"
)
func main() {
// set your Firebolt credentials to construct a dsn string
clientId := ""
clientSecret := ""
accountName := ""
databaseName := ""
dsn := fmt.Sprintf("firebolt:///%s?account_name=%s&client_id=%s&client_secret=%s", databaseName, accountName, clientId, clientSecret)
// open a Firebolt connection
db, err := sql.Open("firebolt", dsn)
if err != nil {
fmt.Printf("error during opening a driver: %v", err)
}
// create a streaming context
streamingCtx := fireboltContext.WithStreaming(context.Background())
// execute a large select query
rows, err := db.QueryContext(streamingCtx, "SELECT \"abc\" FROM generate_series(1, 100000000)")
if err != nil {
fmt.Printf("error during select query: %v", err)
}
// iterating over the result is exactly the same as in the previous example
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("error during rows.Close(): %v\n", err)
}
}()
for rows.Next() {
var id int
if err := rows.Scan(&id); err != nil {
fmt.Printf("error during scan: %v", err)
}
fmt.Println(id)
}
if err := rows.Err(); err != nil {
fmt.Printf("error during rows iteration: %v\n", err)
}
}
If you enable streaming the result, the query execution might finish successfully, but the actual error might be returned during the iteration over the rows.
Although, all interfaces are available, not all of them are implemented or could be implemented:
driver.Result
is a dummy implementation and doesn't return the real result values.- Named query parameters are not supported