diff --git a/driver/driver.go b/driver/driver.go index 1675dd2..45c4b85 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -52,6 +52,11 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) { if err != nil { return nil, err } + defer func() { + if err != nil { + c.Close() + } + }() var pragmas bool c.txBegin = "BEGIN" @@ -65,7 +70,6 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) { case "deferred", "immediate", "exclusive": c.txBegin = "BEGIN " + s default: - c.Close() return nil, fmt.Errorf("sqlite3: invalid _txlock: %s", s) } @@ -73,9 +77,8 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) { } } if !pragmas { - err := c.Conn.Exec(`PRAGMA busy_timeout=60000`) + err = c.Conn.Exec(`PRAGMA busy_timeout=60000`) if err != nil { - c.Close() return nil, err } c.reusable = true @@ -86,7 +89,6 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) { PRAGMA_query_only; `) if err != nil { - c.Close() return nil, err } if s.Step() { @@ -95,7 +97,6 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) { } err = s.Close() if err != nil { - c.Close() return nil, err } } diff --git a/ext/unicode/unicode_test.go b/ext/unicode/unicode_test.go index 6d9b085..3f37ff4 100644 --- a/ext/unicode/unicode_test.go +++ b/ext/unicode/unicode_test.go @@ -2,6 +2,7 @@ package unicode import ( "errors" + "reflect" "testing" "github.com/ncruces/go-sqlite3" @@ -62,6 +63,67 @@ func TestRegister(t *testing.T) { } }) } + + err = db.Close() + if err != nil { + t.Fatal(err) + } +} + +func TestRegister_collation(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + Register(db) + + err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO words (word) VALUES ('côte'), ('cote'), ('coter'), ('coté'), ('cotée'), ('côté')`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`SELECT icu_load_collation('fr_FR', 'french')`) + if err != nil { + t.Fatal(err) + } + + stmt, _, err := db.Prepare(`SELECT word FROM words ORDER BY word COLLATE french`) + if err != nil { + t.Fatal(err) + } + defer stmt.Close() + + got, want := []string{}, []string{"cote", "coté", "côte", "côté", "cotée", "coter"} + + for stmt.Step() { + got = append(got, stmt.ColumnText(0)) + } + if err := stmt.Err(); err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(got, want) { + t.Error("not equal") + } + + err = stmt.Close() + if err != nil { + t.Fatal(err) + } + + err = db.Close() + if err != nil { + t.Fatal(err) + } } func TestRegister_error(t *testing.T) { @@ -99,13 +161,31 @@ func TestRegister_error(t *testing.T) { t.Errorf("got %v, want sqlite3.ERROR", err) } - err = db.Exec(`SELECT 'hello' LIKE 'HELLO' ESCAPE '\\' `) + err = db.Exec(`SELECT 'hello' LIKE 'HELLO' ESCAPE '\\'`) if err == nil { t.Error("want error") } if !errors.Is(err, sqlite3.ERROR) { t.Errorf("got %v, want sqlite3.ERROR", err) } + + err = db.Exec(`SELECT icu_load_collation('enUS', 'error')`) + if err == nil { + t.Error("want error") + } + if !errors.Is(err, sqlite3.ERROR) { + t.Errorf("got %v, want sqlite3.ERROR", err) + } + + err = db.Exec(`SELECT icu_load_collation('enUS', '')`) + if err != nil { + t.Error(err) + } + + err = db.Close() + if err != nil { + t.Fatal(err) + } } func Test_like2regex(t *testing.T) { diff --git a/func_test.go b/func_test.go index 4778b46..581e090 100644 --- a/func_test.go +++ b/func_test.go @@ -18,6 +18,7 @@ func ExampleConn_CreateCollation() { if err != nil { log.Fatal(err) } + defer db.Close() err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`) if err != nil { @@ -46,16 +47,6 @@ func ExampleConn_CreateCollation() { if err := stmt.Err(); err != nil { log.Fatal(err) } - - err = stmt.Close() - if err != nil { - log.Fatal(err) - } - - err = db.Close() - if err != nil { - log.Fatal(err) - } // Output: // cote // coté @@ -70,6 +61,7 @@ func ExampleConn_CreateFunction() { if err != nil { log.Fatal(err) } + defer db.Close() err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`) if err != nil { @@ -100,16 +92,6 @@ func ExampleConn_CreateFunction() { if err := stmt.Err(); err != nil { log.Fatal(err) } - - err = stmt.Close() - if err != nil { - log.Fatal(err) - } - - err = db.Close() - if err != nil { - log.Fatal(err) - } // Unordered output: // COTE // COTÉ @@ -124,6 +106,7 @@ func ExampleContext_SetAuxData() { if err != nil { log.Fatal(err) } + defer db.Close() err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`) if err != nil { @@ -164,16 +147,6 @@ func ExampleContext_SetAuxData() { if err := stmt.Err(); err != nil { log.Fatal(err) } - - err = stmt.Close() - if err != nil { - log.Fatal(err) - } - - err = db.Close() - if err != nil { - log.Fatal(err) - } // Unordered output: // cote // côte diff --git a/func_win_test.go b/func_win_test.go index ef23bff..5832161 100644 --- a/func_win_test.go +++ b/func_win_test.go @@ -14,6 +14,7 @@ func ExampleConn_CreateWindowFunction() { if err != nil { log.Fatal(err) } + defer db.Close() err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`) if err != nil { @@ -42,16 +43,6 @@ func ExampleConn_CreateWindowFunction() { if err := stmt.Err(); err != nil { log.Fatal(err) } - - err = stmt.Close() - if err != nil { - log.Fatal(err) - } - - err = db.Close() - if err != nil { - log.Fatal(err) - } // Output: // 1 // 2