Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

database/sql: Ability to get drivername from instance #12600

Open
pedromorgan opened this issue Sep 12, 2015 · 16 comments
Open

database/sql: Ability to get drivername from instance #12600

pedromorgan opened this issue Sep 12, 2015 · 16 comments
Assignees
Milestone

Comments

@pedromorgan
Copy link

@pedromorgan pedromorgan commented Sep 12, 2015

I'd like to be able to get the driver name..

eg

Db, err = sql.Open("mysql", "root:root@/somestuff")
fmt.Printf("Driver= ",  Db.Driver.Name) << Need...

Case Example.. I want to derive an sqlx instance from an existing connection

// Currently
func SetupDb( driver string, db *sql.DB){
    Dbx = sqlx.NewDb(db, driver)
}
// Wanted
func SetupDb( db *sql.DB){
    Dbx = sqlx.NewDb(db, db.Driver.Name)
}

https://github.com/daffodil/go-mailkit/blob/master/postfixadmin/setup.go#L15

@bradfitz

This comment has been minimized.

Copy link
Contributor

@bradfitz bradfitz commented Oct 10, 2015

I don't know what an sqlx is. When you open a *DB with https://golang.org/pkg/database/sql/#Open , can't you just remember the mapping between (driverName, dataSourceName) and the *DB yourself?

@bradfitz bradfitz changed the title database/sql : Ability to get drivername from instance database/sql: Ability to get drivername from instance Oct 10, 2015
@pedromorgan

This comment has been minimized.

Copy link
Author

@pedromorgan pedromorgan commented Oct 16, 2015

In this case, I am trying to avoid having to store another variable with the driver name and having to pass it around. Expect it could be added to the Db instance itself for convenienace instead.

@bradfitz

This comment has been minimized.

Copy link
Contributor

@bradfitz bradfitz commented Oct 16, 2015

Maybe we could add it to DBStats, so we don't add new methods to DB and users can just use the existing Stats method.

@bradfitz bradfitz added this to the Unplanned milestone Oct 16, 2015
@kardianos kardianos self-assigned this Nov 28, 2016
@msaron

This comment has been minimized.

Copy link

@msaron msaron commented Feb 27, 2017

I need this functionality also. I am using some external libraries and they want the database connection and the driver name (as string).

@kardianos

This comment has been minimized.

Copy link
Contributor

@kardianos kardianos commented Mar 30, 2017

One way you can do this today is to get the DB.Driver() and reflect on that type.

See https://github.com/golang-sql/sqlexp/blob/c2488a8be21d20d31abf0d05c2735efd2d09afe4/quoter.go#L46
for an example. It isn't foolproof as driver type names may change, but they usually don't.

@pedromorgan

This comment has been minimized.

Copy link
Author

@pedromorgan pedromorgan commented Mar 30, 2017

Well thats one way to skin a cat, what I am having to do as a workaroundzzz,
is pass a struct{driver+creds+ nick+stuff} around....

and it seems daft to me that there is not a "field" for the want of the word that simply contains the driver_name and some meta data..

Example case.. Here u are with a new db connection... and a new project..
So before i start to even load that, I need to run around all the db admins asking ? which engine is this code using ?

so its daft.. in my case btw i run www sites + scripts and interfacing db's of all types.. so this is a "bane of contention" as I now need to move around all driver info et all, instead of a DB "object" that COULD do that for me.. Its a simple solution and i dont unserstand quite why it aint there.. to be honest..

https://golang.org/pkg/database/sql/driver/#Driver

type Driver interface {
        // Open returns a new connection to the database.
        // The name is a string in a driver-specific format.
        //
        // Open may return a cached connection (one previously
        // closed), but doing so is unnecessary; the sql package
        // maintains a pool of idle connections for efficient re-use.
        //
        // The returned connection is only used by one goroutine at a
        // time.
        Open(name string) (Conn, error)
        Name << Sriver caches name for help down line later
}




Anyway. .sorry for rant..

@pedromorgan

This comment has been minimized.

Copy link
Author

@pedromorgan pedromorgan commented Mar 30, 2017

@kardianos Make is "method" or something.. help me .. Im my case I am using multiple db's(as a new integrator)..

@kardianos

This comment has been minimized.

Copy link
Contributor

@kardianos kardianos commented Mar 30, 2017

@pedromorgan You're fine. Are you aware of the DB.Driver method?
https://golang.org/pkg/database/sql/#DB.Driver

Let me think on this though. I created a playground for possible extensions:
https://godoc.org/github.com/golang-sql/sqlexp
as you saw before.

In the meantime I could create something like:

package sqlexp

type Flavor int // Flavor of SQL text.

const (
    Unknown Flavor = iota
    Postgres
    TSQL
    MySQL
    SQLite
)

// DriverFlavor returns the SQL variant used.
//
// Obtain the driver value with the sql.DB.Driver method.
func DriverFlavor(d driver.Driver) Flavor {

}

Then you just have to pass around the *sql.DB, right?

@pedromorgan

This comment has been minimized.

Copy link
Author

@pedromorgan pedromorgan commented Mar 31, 2017

No.. I don't want contstants.. I want to know which driver am using.. from string

If its mysql = No spatial//

The only things I want passed is the Name() of the interface..

Is it postgis ?? is it mysql ?? is it gitsql ?? I need to know that cos I cant even create a connection+addoen unless I know that... !!

Othewise Please implement asap the Reflact Inteterface() which @bradfitz is probally correct in the stats module..

@pedromorgan

This comment has been minimized.

Copy link
Author

@pedromorgan pedromorgan commented Mar 31, 2017

Here is the problem..
https://godoc.org/github.com/freeflightsim/fg-navdb/navdb

I want a local cache vs online one in same interface..

@mattn

This comment has been minimized.

Copy link
Member

@mattn mattn commented Mar 31, 2017

The name should be considered for Flavor vs Dialect. 👍

@kardianos

This comment has been minimized.

Copy link
Contributor

@kardianos kardianos commented Mar 31, 2017

@mattn, yeah, Dialect would probably be a better name. I don't think this needs to be in the std lib right away. I'll prototype something in sqlexp.

@pedromorgan I may not be completly understanding your usecase, but if you want to see if postgresql has the postgis extensions installed, that seems like a capability you would query initially when connection. But I'm not arguing with you, a name would be useful attached to a driver. Let me work something up.

@rbranson

This comment has been minimized.

Copy link

@rbranson rbranson commented Apr 3, 2018

FWIW, this "hack" worked for me:

var sqlDriverNamesByType map[reflect.Type]string

// The database/sql API doesn't provide a way to get the registry name for
// a driver from the driver type.
func sqlDriverToDriverName(driver driver.Driver) string {
  if sqlDriverNamesByType == nil {
    sqlDriverNamesByType = map[reflect.Type]string{}

    for _, driverName := range sql.Drivers() {
      // Tested empty string DSN with MySQL, PostgreSQL, and SQLite3 drivers.
      db, _ := sql.Open(driverName, "")

      if db != nil {
        driverType := reflect.TypeOf(db.Driver())
        sqlDriverNamesByType[driverType] = driverName
      }
    }
  }

  driverType := reflect.TypeOf(driver)
  if driverName, found := sqlDriverNamesByType[driverType]; found {
    return driverName
  }

  return ""
}
@winjeg

This comment has been minimized.

Copy link

@winjeg winjeg commented Aug 23, 2019

I encountered the same problem.
In my case, I want to write some middleware without leting the users care about which database type they use.

func init(db *sql.DB) {
   swith(getDbType(db)) {
        case "mysql":
            // logic 1
        case "oracle":
           // logic 2
        case "postgres":
          // logic 3

   }
}
@filinvadim

This comment has been minimized.

Copy link

@filinvadim filinvadim commented Dec 3, 2019

SELECT version(); and parsing response after helps me. Not a best idea i know.

@andreynering

This comment has been minimized.

Copy link

@andreynering andreynering commented Dec 22, 2019

As an author of database libraries that work with multiple drivers (PostgreSQL, MySQL, SQLite, MSSQL, etc) I also think it'd be extremely useful to be able to detect which driver the user is using (without having to ask for an additional parameter).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants
You can’t perform that action at this time.