1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 func newTestDB(t *testing.T, name string) *DB {
14 db, err := Open("test", "foo")
16 t.Fatalf("Open: %v", err)
18 if _, err := db.Exec("WIPE"); err != nil {
19 t.Fatalf("exec wipe: %v", err)
22 exec(t, db, "CREATE|people|name=string,age=int32,dead=bool")
23 exec(t, db, "INSERT|people|name=Alice,age=?", 1)
24 exec(t, db, "INSERT|people|name=Bob,age=?", 2)
25 exec(t, db, "INSERT|people|name=Chris,age=?", 3)
30 func exec(t *testing.T, db *DB, query string, args ...interface{}) {
31 _, err := db.Exec(query, args...)
33 t.Fatalf("Exec of %q: %v", query, err)
37 func closeDB(t *testing.T, db *DB) {
40 t.Fatalf("error closing DB: %v", err)
44 func TestQuery(t *testing.T) {
45 db := newTestDB(t, "people")
47 rows, err := db.Query("SELECT|people|age,name|")
49 t.Fatalf("Query: %v", err)
58 err = rows.Scan(&r.age, &r.name)
60 t.Fatalf("Scan: %v", err)
66 t.Fatalf("Err: %v", err)
69 {age: 1, name: "Alice"},
70 {age: 2, name: "Bob"},
71 {age: 3, name: "Chris"},
73 if !reflect.DeepEqual(got, want) {
74 t.Logf(" got: %#v\nwant: %#v", got, want)
78 func TestRowsColumns(t *testing.T) {
79 db := newTestDB(t, "people")
81 rows, err := db.Query("SELECT|people|age,name|")
83 t.Fatalf("Query: %v", err)
85 cols, err := rows.Columns()
87 t.Fatalf("Columns: %v", err)
89 want := []string{"age", "name"}
90 if !reflect.DeepEqual(cols, want) {
91 t.Errorf("got %#v; want %#v", cols, want)
95 func TestQueryRow(t *testing.T) {
96 db := newTestDB(t, "people")
101 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
102 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
103 t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
106 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
108 t.Fatalf("age QueryRow+Scan: %v", err)
111 t.Errorf("expected name Bob, got %q", name)
114 t.Errorf("expected age 2, got %d", age)
117 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
119 t.Fatalf("name QueryRow+Scan: %v", err)
122 t.Errorf("expected name Alice, got %q", name)
125 t.Errorf("expected age 1, got %d", age)
129 func TestStatementErrorAfterClose(t *testing.T) {
130 db := newTestDB(t, "people")
132 stmt, err := db.Prepare("SELECT|people|age|name=?")
134 t.Fatalf("Prepare: %v", err)
138 t.Fatalf("Close: %v", err)
141 err = stmt.QueryRow("foo").Scan(&name)
143 t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
147 func TestStatementQueryRow(t *testing.T) {
148 db := newTestDB(t, "people")
150 stmt, err := db.Prepare("SELECT|people|age|name=?")
152 t.Fatalf("Prepare: %v", err)
155 for n, tt := range []struct {
163 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
164 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
165 } else if age != tt.want {
166 t.Errorf("%d: age=%d, want %d", n, age, tt.want)
172 // just a test of fakedb itself
173 func TestBogusPreboundParameters(t *testing.T) {
174 db := newTestDB(t, "foo")
176 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
177 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
179 t.Fatalf("expected error")
181 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
182 t.Errorf("unexpected error: %v", err)
186 func TestExec(t *testing.T) {
187 db := newTestDB(t, "foo")
189 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
190 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
192 t.Errorf("Stmt, err = %v, %v", stmt, err)
195 type execTest struct {
199 execTests := []execTest{
201 {[]interface{}{"Brad", 31}, ""},
202 {[]interface{}{"Brad", int64(31)}, ""},
203 {[]interface{}{"Bob", "32"}, ""},
204 {[]interface{}{7, 9}, ""},
206 // Invalid conversions:
207 {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting Exec argument #1's type: sql/driver: value 4294967295 overflows int32"},
208 {[]interface{}{"Brad", "strconv fail"}, "sql: converting Exec argument #1's type: sql/driver: value \"strconv fail\" can't be converted to int32"},
210 // Wrong number of args:
211 {[]interface{}{}, "sql: expected 2 arguments, got 0"},
212 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
214 for n, et := range execTests {
215 _, err := stmt.Exec(et.args...)
220 if errStr != et.wantErr {
221 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
222 n, et.args, errStr, et.wantErr)
227 func TestTxStmt(t *testing.T) {
228 db := newTestDB(t, "")
230 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
231 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
233 t.Fatalf("Stmt, err = %v, %v", stmt, err)
235 tx, err := db.Begin()
237 t.Fatalf("Begin = %v", err)
239 _, err = tx.Stmt(stmt).Exec("Bobby", 7)
241 t.Fatalf("Exec = %v", err)
245 t.Fatalf("Commit = %v", err)
249 // Tests fix for issue 2542, that we release a lock when querying on
250 // a closed connection.
251 func TestIssue2542Deadlock(t *testing.T) {
252 db := newTestDB(t, "people")
254 for i := 0; i < 2; i++ {
255 _, err := db.Query("SELECT|people|age,name|")
257 t.Fatalf("expected error")