goen v0.0.6について

BulkCompilerに対して、MaxChunksが指定できるようになりました。 これまでは大量のプレースホルダを持つクエリを生成したとき、クエリ実行時にエラーになっていました。

package main

import (
    "database/sql"
    "fmt"

    "github.com/kamichidu/goen"
    _ "github.com/kamichidu/goen/dialect/sqlite3"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        panic(err)
    }
    defer db.Close()

    _, err = db.Exec(`create table users (user_id, name)`)
    if err != nil {
        panic(err)
    }

    dbc := goen.NewDBContext("sqlite3", db)
    dbc.Compiler = goen.BulkCompiler
    for i := 0; i < 1000; i++ {
        dbc.Patch(goen.InsertPatch("users", []string{"user_id", "name"}, []interface{}{i, "testing"}))
    }

    // 実行時に以下エラーが発生する
    // panic: too many SQL variables
    if err := dbc.SaveChanges(); err != nil {
        panic(err)
    }

    type Res struct {
        Count int
    }
    var res []Res
    rows, err := dbc.Query(`select count(*) as count from users`)
    if err != nil {
        panic(err)
    }
    defer rows.Close()

    if err := dbc.Scan(rows, &res); err != nil {
        panic(err)
    }
    fmt.Printf("number of rows %d\n", res[0].Count)
}

BulkComoilerに対してMaxChunksを指定することで、回避が可能になりました。

package main

import (
    "database/sql"
    "fmt"

    "github.com/kamichidu/goen"
    _ "github.com/kamichidu/goen/dialect/sqlite3"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        panic(err)
    }
    defer db.Close()

    _, err = db.Exec(`create table users (user_id, name)`)
    if err != nil {
        panic(err)
    }

    dbc := goen.NewDBContext("sqlite3", db)
    dbc.Compiler = &goen.BulkCompilerOptions{
        // 最大で100パッチを1つのクエリにまとめる
        MaxPatches: 100,
    }
    for i := 0; i < 1000; i++ {
        dbc.Patch(goen.InsertPatch("users", []string{"user_id", "name"}, []interface{}{i, "testing"}))
    }

    if err := dbc.SaveChanges(); err != nil {
        panic(err)
    }

    type Res struct {
        Count int
    }
    var res []Res
    rows, err := dbc.Query(`select count(*) as count from users`)
    if err != nil {
        panic(err)
    }
    defer rows.Close()

    if err := dbc.Scan(rows, &res); err != nil {
        panic(err)
    }
    fmt.Printf("number of rows %d\n", res[0].Count)
}

1つのクエリに含めることができるプレースホルダ数をパラメータにしなかった理由は、ドライバごとに取得可否が分かれるためです。 最大プレースホルダ数の指定で確実に問題が回避できるようなら、将来的に別のオプションを追加するかもしれません。 現状では、1つのクエリにマージするパッチ数を調整することで、実行時エラーを回避する方針としています。