sibert
sibert

Reputation: 2228

Moving query to handler gets "undefined: db" (golang)

I am trying to use Golang as a REST API. I have managed to get handlers to work and queries as well. But not got a query inside a handler to work.

When the query resides within the main() it works:

func handleRequests() {
    http.HandleFunc("/getuser", Getuser)
}

---> this handler gets respons on localhost:8080/getuser

func Getuser(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Getuser")
}

func main() {
    handleRequests()

    //Connect to db

    rows, err := db.Queryx(`SELECT "USER_ID","USER_NAME" FROM user`)
    for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
    fmt.Printf("%#v\n", results)
    }

    log.Fatal(http.ListenAndServe(":8080", nil))
}

But when I move the query to the handler it gives an error that the db is not defined.

func handleRequests() {
    http.HandleFunc("/getuser", Getuser)
}

---> this gives the error that the db is not defined

func Getuser(w http.ResponseWriter, r *http.Request) {
    rows, err := db.Queryx(`SELECT "USER_ID","USER_NAME" FROM user`)
    for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
    fmt.Printf("%#v\n", results)
    }
}

func main() {
    handleRequests()

    //Connect to db

    log.Fatal(http.ListenAndServe(":8080", nil))
 }

EDIT

Full code inside the handler (added db var as suggested), but gives various errors on "err".

 var db *sqlx.DB <---solved the db problem

 func Getsign(w http.ResponseWriter, r *http.Request) {
    rows, err := db.Queryx(`SELECT "USER_ID","USER_NAME" FROM user`)
    for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
        fmt.Printf("%#v\n", results)
    }

    defer rows.Close()

    if err := rows.Err(); err != nil {
        log.Fatal(err)
    }
}

Any tip what I am doing wrong?

Upvotes: 3

Views: 2584

Answers (2)

Kugel
Kugel

Reputation: 838

Define your db variable outside of main, e.g.:

var db *sql.DB

func handler(w http.ResponseWriter, r *http.Request) {
    rows, err := db.Query(...)
    // use it
}

func main() {
    db, _ = sql.Open(...)
}

Upvotes: 5

Bestbug
Bestbug

Reputation: 485

For what I can see with the code you posted (next time I suggest to post the full code) you are declaring the db variable on the main function but you are referring it in a function who have no visibility of that variable. In order to fix the problem you have various way. the easiest way is to declare a global variable like var db typename and on the main function don't use the := assign but only =. In this mode you can set the global variable (in the other case you are create a local variable named db in the main function). Note in a concurrency environment this could be a problem, consider to study your driver library to see if have some guarantee about concurrency or best practice.

Upvotes: 0

Related Questions