Go のクエリビルダ squirrel で IN 句を使ったクエリを書く

はじめに

自戒をこめて書きます. Go のクエリビルダ squirrel で IN 句を使ったクエリを書く方法です.

要点

何も考えずに配列を渡せばいい. squirrel がよしなにやってくれる.

q, a, err := squirrel.
    Select("columns").
    From("table_name").
    Where(squirrel.Eq{"some_id": someIds}).
    ToSql()
if err != nil {
    // エラー処理
}

本文

はじめは squirrel を使って IN 句を使ったクエリを書く方法がわからず,素直に内部実装を読めばいいものを未熟な私は gg って解決しようとしました. そこで「sqlx.In を併用することで解決する」旨の記事を見つけました. 私はその内容を鵜呑みにし,しばらく sqlx.In を使ったコードを量産していました.

inq, ina, err := sqlx.In("some_id IN (?)", someIds...)
if err != nil {
    // エラー処理
}
q, a, err := squirrel.Select("columns").From("table_name").Where(inq, ina...).ToSql()
if err != nil {
    // エラー処理
}

あるときにリファクタリングをして貰う機会があり, squirrel.Where および Squirrel.Eq に配列を渡すことでよしなに IN 句を含むクエリを返してくれるので sqlx.In を使わなくてもいいと指摘をいただきました.

q, a, err := squirrel.Select("columns").From("table_name").Where(squirrel.Eq{"some_id": someIds}).ToSql()
if err != nil {
    // エラー処理
}

考えてみたらそうですよね. 広く使われているのに In 句に対応できないわけがない. 大体のクエリビルダってこうなっているんですかね.

困ったときには 内部実装 をしっかり読んでみようと思いました. 読めない量ではないですし,何よりコードは書いたとおりにしか動かないものですし.