The usual way to interact with SQL databases in Go is to use the database/sql module. While I have been interacting with PostgreSQL in Go for some time, I’m used to github.com/jackc/pgx. I recently started using an SQLite database from a Go program, and the most mature solution seems to be github.com/mattn/go-sqlite3 which is a driver for database/sql.

The interface of the sql module is very simple: you run queries and get a Rows object in return. You can then call the Scan() method to fill values from each column of each row.

sql also has a QueryRow() method which is used to fetch a single row. However this method returns a Row object. This object also has an identical Scan() method.

When writing code to manipulate objects stored in the database, you need various methods which will perform different SELECT-based SQL requests. Each method executes the request, goes through the resulting rows, and extract values using Scan(). So you want a method which takes a Rows parameter and fill a structure representing an object. But if you have a Row coming from QueryRow(), you cannot use the same method. And while Row is just an encapsulation of a Rows object, the rows member is private, so you cannot convert a Row into a Rows to pass it to the scanning method.

I came up with the following trick. Let’s define an interface containing the Scan() method:

type DBScannable interface {
	Scan(...interface{}) error
}

Then the scanning method can take a DBScannable parameter. And since both Rows and Row have a Scan() method that matches this definition, they both implement the interface. Therefore the method can be called with either Row or Rows instances.

So you can have a scanning method which can be used for both Query() and QueryRow() and avoids a lot of code duplication.