sql connection shared between different package files

161 views
Skip to first unread message

eauction...@hotmail.com

unread,
Mar 16, 2015, 4:54:09 PM3/16/15
to golan...@googlegroups.com
I have tried for days to get my head round this, all i want to do is open a mysql database once, with a global db variable and then in different package files within the app use that same db variable to access the files,

here is what I have so far

C:\go\src\testsql\dbpackage\dbpackage.go

import (
    "database/sql"
    "fmt"
)

var Db *sql.DB

func init() {

    Db, err := sql.Open("mysql",
        "remoteusername:remotepassord@tcp(remoteipaddress:3306)/remotedatabasename")
    if err != nil {
        fmt.Printf("openind db: error: %s\n", err)
    }
    err = Db.Ping()
    if err != nil {
        // do something here, we cant ping the database connection we just made.
        fmt.Printf("pinging db: error: %s\n", err)
    }

}

as I understand it the Db should be globally accessible, having a capital first letter? Correct or not?

Then I also have

c:\go\src\testsql\main.go

package main
import (     "fmt"     "testsql/dbpackage" )
func main() {     var (         id int         title string     )     rows, err := dbpackage.Db.Query("select id, title from pages where id < ?", 100)
    if err != nil {         fmt.Printf("select statement: error: %s\n", err)     }     defer rows.Close()     for rows.Next() {         err := rows.Scan(&id, &title)         if err != nil {             fmt.Printf("read row: error: %s\n", err)         }         fmt.Printf("%d %s\n", id, title)     }     err = rows.Err()     if err != nil {         fmt.Printf("final: error: %s\n", err)     } }


However, running this crashes out with

C:/Go/bin/go.exe build -i [C:/Go/src/testsql]

Success: process exited with code 0.

C:/Go/src/testsql/testsql.exe [C:/Go/src/testsql]

openind db: error: sql: unknown driver "mysql" (forgotten import?)

panic: runtime error: invalid memory address or nil pointer dereference

[signal 0xc0000005 code=0x1 addr=0x0 pc=0x48a2f5]


goroutine 1 [running]:

database/sql.(*DB).conn(0x0, 0x43, 0x0, 0x0)

c:/go/src/database/sql/sql.go:634 +0x7b5

database/sql.(*DB).Ping(0x0, 0x0, 0x0)

c:/go/src/database/sql/sql.go:462 +0x41

testsql/dbpackage.init·1()

C:/Go/src/testsql/dbpackage/dbpackage.go:17 +0x14d

testsql/dbpackage.init()

C:/Go/src/testsql/dbpackage/dbpackage.go:23 +0x53

main.init()

C:/Go/src/testsql/main.go:31 +0x49


goroutine 2 [runnable]:

runtime.forcegchelper()

c:/go/src/runtime/proc.go:90

runtime.goexit()

c:/go/src/runtime/asm_amd64.s:2232 +0x1


goroutine 3 [runnable]:

runtime.bgsweep()

c:/go/src/runtime/mgc0.go:82

runtime.goexit()

c:/go/src/runtime/asm_amd64.s:2232 +0x1


goroutine 4 [runnable]:

runtime.runfinq()

c:/go/src/runtime/malloc.go:712

runtime.goexit()

c:/go/src/runtime/asm_amd64.s:2232 +0x1

Error: process exited with code 2.


Can anyone help me grasp what I am missing with this, I feel like I am missing something pretty fundemental...




 


silviun...@gmail.com

unread,
Mar 16, 2015, 5:01:55 PM3/16/15
to golan...@googlegroups.com, eauction...@hotmail.com
you appear to have forgotten the reference to the mysql driver in the dbpackage file

Import one of the mysql drivers  (first, do: go get github.com/go-sql-driver/mysql )

Then, add a line in your imports section in dbpackage.go


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

eauction...@hotmail.com

unread,
Mar 16, 2015, 5:09:55 PM3/16/15
to golan...@googlegroups.com, eauction...@hotmail.com
many thanks, I had forgot about that when I stripped the code out to make the example one for testing.
I have put the line into dbpackage.go, and imported the driver but it still crashes out with the following message


C:/Go/bin/go.exe build -i [C:/Go/src/testsql]

Success: process exited with code 0.

C:/Go/src/testsql/testsql.exe [C:/Go/src/testsql]

panic: runtime error: invalid memory address or nil pointer dereference

[signal 0xc0000005 code=0x1 addr=0x0 pc=0x4938e5]


goroutine 1 [running]:

database/sql.(*DB).conn(0x0, 0x0, 0x0, 0x0)

c:/go/src/database/sql/sql.go:634 +0x7b5

database/sql.(*DB).query(0x0, 0x6aa150, 0x28, 0xc082063f48, 0x1, 0x1, 0x40b003, 0x0, 0x0)

c:/go/src/database/sql/sql.go:933 +0x4a

database/sql.(*DB).Query(0x0, 0x6aa150, 0x28, 0xc082063f48, 0x1, 0x1, 0x0, 0x0, 0x0)

c:/go/src/database/sql/sql.go:924 +0xad

main.main()

C:/Go/src/testsql/main.go:14 +0x151


goroutine 5 [chan receive]:

database/sql.(*DB).connectionOpener(0xc08202ebe0)

c:/go/src/database/sql/sql.go:589 +0x53

created by database/sql.Open

c:/go/src/database/sql/sql.go:452 +0x323

Error: process exited with code 2.




Ingo Oeser

unread,
Mar 16, 2015, 5:27:00 PM3/16/15
to golan...@googlegroups.com
It'a scoping problem.
the Db variable in your init function is shadowing the global Db variable.

Try this
func init() {
var err error
Db , err = db.Open(.....)
// note the equals instead of colon equals above!
//....
}

eauction...@hotmail.com

unread,
Mar 16, 2015, 5:55:25 PM3/16/15
to golan...@googlegroups.com, eauction...@hotmail.com
THANK YOU

works a treat now, so it was because i was trying to create a new variable with := rather than just assigning it to the existing global!

for future reference for anyone with same problem, the updated func which works is as follows


func init() {

    var err error
    Db, err = sql.Open("mysql",
        "remoteuser:remotepassword@tcp(ipaddress:3306)/databasename")
    // note the equals instead of colon equals above!
    
    if err != nil {
        fmt.Printf("openind db: error: %s\n", err)
    }
    err = Db.Ping()
    if err != nil {
        // do something here, we cant ping the database connection we just made.
        fmt.Printf("pinging db: error: %s\n", err)
    }

}


thanks again, now I can crack on and start some serious learning :)

On Monday, 16 March 2015 20:54:09 UTC, eauction...@hotmail.com wrote:
Reply all
Reply to author
Forward
0 new messages