sensorario
sensorario

Reputation: 21698

replace variables with structs queriing with golang

I've this snippet of code that works:

db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
if err != nil {
    panic(err.Error())
}
rows, err := db.Query("select username from users")
if err != nil {
    panic(err.Error())
}
var (
    username string
)
for rows.Next() {
    err = rows.Scan(
        &name,
    )
    if err != nil {
        panic(err)
    }
    fmt.Println(username)
}

But, ... is it possible to substitute

var (
    username string
)

and err = rows.Scan( &name, )

with a struct?

I ask this because every time I want to add new field I need to

May I define a struct and update fields in just one place? Or, ... are there some best practice to build queries and fetch them?

Upvotes: 0

Views: 1535

Answers (2)

RayfenWindspear
RayfenWindspear

Reputation: 6284

If you are willing to use a library, https://github.com/jmoiron/sqlx is perfect for the job.

place := Place{}
rows, err := db.Queryx("SELECT * FROM place")
for rows.Next() {
    err := rows.StructScan(&place)
    if err != nil {
        log.Fatalln(err)
    } 
    fmt.Printf("%#v\n", place)
}

There is some basic usage in the github readme https://github.com/jmoiron/sqlx as well as some "standard" documentation the maintainer has written http://jmoiron.github.io/sqlx/ and finally, the godoc http://godoc.org/github.com/jmoiron/sqlx

One thing to note, is that sqlx made the design choice similar to the way the go compiler forces you to use variables that you have created. So if you select a column that isn't in your struct, it throws an error. The reasons for this are sound and promote good sql practices. Select * when you only need one column is crazy expensive. See his notes here http://jmoiron.github.io/sqlx/#safety

Upvotes: 1

TehSphinX
TehSphinX

Reputation: 7440

You can do something like this:

type user struct {
    Name  string
    Pass  string
    Email string
    Age   int
}

func main() {
    db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
    if err != nil {
        panic(err.Error())
    }
    rows, err := db.Query("select user, pass, email, age from users")
    if err != nil {
        panic(err.Error())
    }
    var (
        users []user
    )
    for rows.Next() {
        u := user{}
        err = rows.Scan(
            &u.Name, &u.Pass, &u.Email, &u.Age,
        )
        if err != nil {
            panic(err)
        }

        users = append(users, u)
    }
    fmt.Println(users)
}

Upvotes: 2

Related Questions