Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I compile a Go database/sql program with multiple drivers?

Tags:

sql

go

I'm writing a test program in Go for sql databases (Postgres and Mysql) currently. I don't know much about the "_" option for packages however I am using it (see below).

What I would like to be able to do is to compile once to use multiple sql drivers for the one RDBMS and also for multiple RDBMS's and when running the program, select which driver and RDBMS to use. I'm not sure if that's possible. Currently I compile with one Postgres and one Mysql driver and then select which one I'm using at run time (Postgres/Mysql). That works OK, but I need to remember which driver was compiled. It would be good to be able to compile with multiple drivers for the one RDBMS and then at run-time select which one to use. I guess that's not possible. Alternatively it would be good to be able to select at compile time which drivers to use, and at run-time to know which drivers are being used. Without one of these facilities, one could be testing eg. Postgres and think they are using one driver when in fact the program has been compiled with another driver.

Is it possible to have a compiler option to select particular drivers, and then at run-time know which driver is being used? An alternative is obviously to edit the program to indicate this.

An example of the import is as follows :

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    ////_ "github.com/lib/pq"
    _ "github.com/lxn/go-pgsql"
 ........
like image 873
Brian Oh Avatar asked Oct 23 '13 08:10

Brian Oh


1 Answers

I don't know much about the "_" option for packages however I am using it (see below).

Prepending _ to a import path will import the package just normally (running its' init() function) but it won't associate a name in your current package with the imported package.

What I would like to be able to do is to compile once to use multiple sql drivers for the one RDBMS and also for multiple RDBMS's and when running the program, select which driver and RDBMS to use. I'm not sure if that's possible.

The init() function of package "github.com/go-sql-driver/mysql" does the following:

func init() {
        sql.Register("mysql", &MySQLDriver{})
}

It will call database/sql's Register function which is defined to be:

func Register(name string, driver driver.Driver)

And has the condition:

If Register is called twice with the same name or if driver is nil, it panics.

After a driver has been registered, you can use sql.Open:

func Open(driverName, dataSourceName string) (*DB, error)

to open a new connection to a database, using the driver specified by the first argument, e.g:

db, e := sql.Open("mysql", "user:pass@host:port")

By the way, github.com/lxn/go-pgsql's init() function looks like this:

func init() {
        sql.Register("postgres", sqlDriver{})
}

I have re-read your question and I think that additionally, you'd like to specify what database and driver you want to use when running the program.

For this, you can use the flag package and run your application like this:

./my_app -driver=mysql -db="user:pass@host:port"

and pass these strings to sql.Open.

like image 103
thwd Avatar answered Sep 18 '22 02:09

thwd