I'm new to GO, and can't seem to find any information on an error with reusing a database connection in a global. Here's a simplified version of my code that caues the error:
package main
import (
_ "github.com/denisenkom/go-mssqldb"
"database/sql"
)
var debug = flag.Bool("debug", false, "enable debugging")
var password = flag.String("password", "*****", "the database password")
var port *int = flag.Int("port", 1433, "the database port")
var server = flag.String("server", "localhost", "the database server")
var user = flag.String("user", "*****", "the database user")
var db *sql.DB
func main() {
// Parse the incoming flags to set variables.
flag.Parse()
// Output the database variables if the debug flag is set.
if *debug {
fmt.Printf(" password:%s
", *password)
fmt.Printf(" port:%d
", *port)
fmt.Printf(" server:%s
", *server)
fmt.Printf(" user:%s
", *user)
}
// Build out the connection string to the database, and then open the connection to the database.
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d", *server, *user, *password, *port)
if *debug { fmt.Printf(" connString:%s
", connString) }
db, err := sql.Open("mssql", connString)
if err != nil { log.Fatal("Open connection failed:", err.Error()) }
err = db.Ping()
if err != nil {
fmt.Println("Cannot connect: ", err.Error())
return
}
// Close the connection when we're all done.
defer db.Close()
// Truncate the existing records in the ListHubFeed
res, err := db.Exec( `
TRUNCATE TABLE foo
` )
_ = res
if err != nil {
fmt.Println( "TRUNCATE TABLE failed", err )
}
eligible := verifyEligibility( "foo" )
}
func verifyEligibility( email string ) ( success bool ) {
//Run each check individually, and if any one fails, return false and stop processing additional checks
// if the routing email is bad, then we can't create an account, so kick it out.
if( !govalidator.IsEmail( email ) ){
writeToLog( email )
return false
}
return true;
}
func writeToLog( tolog string ) {
res, err := db.Exec(`
INSERT INTO Log (
Email
) VALUES (
?,
?,
?,
?
)` , tolog )
if err != nil {
fmt.Println( "insert failed", err )
}
_ = res
}
That's really ugly psuedocode, but the point is that the TRUNCATE
statements in main
run just fine, but after calling verifyEligibility()
and then attempting to log the entry in the writeToLog()
function, I get the following error:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x46d485]
goroutine 1 [running]:
database/sql.(*DB).conn(0x0, 0xc082044088, 0x0, 0x0)
c:/go/src/database/sql/sql.go:634 +0x7b5
database/sql.(*DB).exec(0x0, 0x742730, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/database/sql/sql.go:884 +0x9d
database/sql.(*DB).Exec(0x0, 0x742730, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/database/sql/sql.go:875 +0xd4
main.writeToLog(0xc082004a20, 0x11, 0x70f370, 0x5, 0x0, 0x0, 0x777ef0, 0x24, 0x71ba70, 0x3)
I can't find any information on this error as it relates to go-mssqldb
. db
is declared as a global, and is opened in main
, so I can't figure out why it's not available to me in writeToLog()
.