20

I'm using the MySQL driver for Golang provided here

https://github.com/go-sql-driver/mysql

One of the things I'm trying to do is store the database variable in a global connection. According to the documentation, sql.Open() is supposed to return a pointer to a DB struct, so I tried storing it as

var db *DB

However, that resulted in the error

undefined: DB

The next thing I tried was to look at the source code for the MySQL driver, and I found a snippet of code here https://github.com/go-sql-driver/mysql/blob/master/driver.go

func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {

So, I tried to save the variable as driver.Conn - however, I was unable to (incorrect imports). I wasn't able to import driver either.

The last thing I tried was to use reflect to bring the name of the variable to light

package main

    import (
        "fmt"
        "reflect"
)

import "database/sql"
import _ "github.com/go-sql-driver/mysql"

func main() {
        db, _ := sql.Open("mysql", "root:password@/Tracker")
        yt := reflect.TypeOf(db).Kind()
        fmt.Printf("%T: %s\n", yt, yt)
}

Unfortunately, that didn't work either - it shows up as pointer, and not the type of variable it's actually pointing to.

I'm at a loss as to how to figure it out now. Thanks in advance for your help!

dreadiscool
  • 1,598
  • 3
  • 18
  • 31

1 Answers1

40

You need to qualify the name of the type with the package name:

import(
    "database/sql"
    "github.com/go-sql-driver/mysql"
)

var db *sql.DB // Note the sql package provides the namespace

func main() {
    var err error
    // Make sure not to shadow your global - just assign with = - don't initialise a new variable and assign with :=
    db, err = sql.Open(...)
    if err != nil {
        // Handle the error!
    }

 }

Whether you want to have a global (easy to get started) or pass it around explicitly is up to you, but I'd suggest just keeping it simple for now. If this is going into a web application, you can safely share the *sql.DB connection pool across handlers/requests.

elithrar
  • 23,364
  • 10
  • 85
  • 104
  • 9
    +1 for the answer. Should declare err separately or else db variable will be come local other function that tried to use db connection will receive "PANIC: runtime error: invalid memory address or nil pointer dereference" error – Ryan Dec 09 '15 at 23:27
  • hey, do you know why we should use pointer here? insetead just var db sql.DB – MisterCat Jan 28 '19 at 08:32
  • 1
    Yes, because `*sql.DB` represents a pool, and using a value will cause it to be copied when passed around. This will result in internal state being incorrect - idle connections untracked, etc. – elithrar Jan 28 '19 at 13:43