Pass sql.DB pointer as method parameter

Asked

Viewed 55 times

1

I have a struct that has a method save receiving as parameter a pointer for access to the seat;

func (c Call) Save(db *sql.DB) error {
    stmt, err := db.Prepare(`
        INSERT INTO calls values($1, $2, $3, $4)
    `)
    if err != nil {
        return err
    }
    // ...
}

but when I pass the pointer as parameter an error panic is displayed;

http: Panic serving [::1]:51111: Runtime error: invalid memory address or nil Pointer dereference

the connection is defined as follows:

import (
    "database/sql"
    _ "github.com/lib/pq"
)

var db *sql.DB

func init() {
    db, _ := sql.Open("postgres", dsn)
    if err := db.Ping(); err != nil {
        log.Fatal(err.Error())
    }
}

The passage of the parameter occurs thus:

err := c.Save(db)
// c é a struct que possui o método Save

Even defining in the method that the parameter is a pointer this error of nil Pointer happens, because?

1 answer

1


I think the problem is the locally created variable. You’re doing something like this:

package main
import "fmt"

var variavel *int

func init() {
    variavel, _ := new(int), new(int)
    fmt.Println("init:", variavel)
}

func main() {
    fmt.Println("main:", variavel)
}

The print will be:

init: 0x416020
main: <nil>

To fix you must use = instead of :=. In this case use variavel, _ = new(int), new(int) would solve.


Exchange the db, _ := sql.Open("postgres", dsn) for db, _ = sql.Open("postgres", sn), so you’ll make the result stay on var db *sql.DB and not in a new local variable of the init():

import (
    "database/sql"
    _ "github.com/lib/pq"
)

var db *sql.DB

func init() {
    db, _ = sql.Open("postgres", dsn) // Usando = ao invés de := 
    if err := db.Ping(); err != nil {
        log.Fatal(err.Error())
    }
}

Another solution is to create another variable, such as:

func init() {
    dbX, _ := sql.Open("postgres", dsn) // Use :=
    if err := db.Ping(); err != nil {
        log.Fatal(err.Error())
    }
    db = dbX // Agora seta o db como valor do dbX, criado acima.
}
  • linter should not report that there are 2 variables with the same name?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.