Golang shorts #2 — Own structScan method for sql.Rows

If you always wondered to do this below, but got an error, I have a good news for you…. Obviously the solution tailored to my necessities, but enough to do something like this.

for rows.Next() {
s := myStruct{}
if err := rows.Scan(&s); err != nil {
return err

// It's not working obviously!

So, 1 hour of investigation, I can introduce the amazing structScan function… TA-DA

Yes, I know the sqlx have a similar function, but if you want to us it, you can’t avoid the whole library, but this solution is based on the built-in database/sql package.

What’s it doing?

Firstly there is an example usage

func main() {
rows, _ := db.Query(query)
defer rows.Close()
s := yourStruct{}
err = structScan(rows, &s)
// handle err

You have to pass a evaluated sql.Rows, and a struct which is represent the sql table layout. (I’m using the json StructTag to determine the column names, because my models are designed to working with NoSQL databases as well).

So the first part of the function is just some quick check for the right behavior, for example the second argument must be a pointer, because if it’s not a pointer it’s not settable through the reflection. This section also get the cols. After that I save everything in a map[string]interface{} by the column name. How I told you the column names determined in the json StructTag, so this is where I do the magic.

The last part is iterate on the Struct fields of the second parameter, getting the json StructTags which will determine the map index and if it isn’t nil, I put them into the struct.

Unfortunately it’s seems so obvious now, but trust me it was a bit hard to figure it out. I also checked the sqlx package solution for that, but it used the other methods of the package. The nice part of that, it’s working as a standalone function. So not require any other package imported, just the built-in solutions.