この記事はGo2 Advent Calendar 2017 13日目の記事です。 昨日は@kami_zh さんの Goで標準出力をキャプチャするパッケージを書いた でした。

go-sqlrow

Go言語で標準パッケージを使用してRDBMSからデータを取ってくるには、以下の様に書きます1

1
2
3
4
5
6
7
8
9
type Person struct {
    ID   string
    Name string
}

db, _ := sql.Open("dn", "dsn")
row, _ := db.Query(`SELECT id, name FROM person where id='foo'`)
var p Person
row.Scan(&p.ID, &p.Name)

SQL文を発行するまではいいのですが、最後の行、sql.Row#Scanがくせ者です。 上記の例のように、sql.row#Scanは可変長個のポインタを引数にとり、それらにそれぞれ値をセットします。この例では値の数が2つのため大きな問題ではありませんが、値の数が増えた場合などは非常に面倒です。また、テーブルの構造が変わった場合なども非常に面倒です。

この問題を解決するため、go-sqlrow という小さなパッケージを作りました2。 これは上記のrow.Scanを代わりにやってくれるパッケージです。

機能・使い方は簡単で、先ほどの例を次の様に書き換えます。

1
2
3
4
5
6
7
8
9
type Person struct {
    ID   string
    Name string
}

db, _ := sql.Open("dn", "dsn")
row, _ := db.Query(`SELECT id, name FROM person where id='foo'`)
var p Person
sqlrow.Bind(row, &p)

後は内部でrow.Scan相当の処理を行います。 unexportedなフィールドはencoding/json同様、sql.Rowとの対応がとれませんので、注意が必要です。


  1. エラー処理やトランザクションなどは省略 ↩︎

  2. godoc: https://godoc.org/github.com/nasa9084/go-sqlrow  ↩︎