OSDN Git Service

libgo: Update to weekly.2011-12-22.
[pf3gnuchains/gcc-fork.git] / libgo / go / exp / sql / sql_test.go
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.
4
5 package sql
6
7 import (
8         "reflect"
9         "strings"
10         "testing"
11 )
12
13 func newTestDB(t *testing.T, name string) *DB {
14         db, err := Open("test", "foo")
15         if err != nil {
16                 t.Fatalf("Open: %v", err)
17         }
18         if _, err := db.Exec("WIPE"); err != nil {
19                 t.Fatalf("exec wipe: %v", err)
20         }
21         if name == "people" {
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)
26         }
27         return db
28 }
29
30 func exec(t *testing.T, db *DB, query string, args ...interface{}) {
31         _, err := db.Exec(query, args...)
32         if err != nil {
33                 t.Fatalf("Exec of %q: %v", query, err)
34         }
35 }
36
37 func closeDB(t *testing.T, db *DB) {
38         err := db.Close()
39         if err != nil {
40                 t.Fatalf("error closing DB: %v", err)
41         }
42 }
43
44 func TestQuery(t *testing.T) {
45         db := newTestDB(t, "people")
46         defer closeDB(t, db)
47         rows, err := db.Query("SELECT|people|age,name|")
48         if err != nil {
49                 t.Fatalf("Query: %v", err)
50         }
51         type row struct {
52                 age  int
53                 name string
54         }
55         got := []row{}
56         for rows.Next() {
57                 var r row
58                 err = rows.Scan(&r.age, &r.name)
59                 if err != nil {
60                         t.Fatalf("Scan: %v", err)
61                 }
62                 got = append(got, r)
63         }
64         err = rows.Err()
65         if err != nil {
66                 t.Fatalf("Err: %v", err)
67         }
68         want := []row{
69                 {age: 1, name: "Alice"},
70                 {age: 2, name: "Bob"},
71                 {age: 3, name: "Chris"},
72         }
73         if !reflect.DeepEqual(got, want) {
74                 t.Logf(" got: %#v\nwant: %#v", got, want)
75         }
76 }
77
78 func TestRowsColumns(t *testing.T) {
79         db := newTestDB(t, "people")
80         defer closeDB(t, db)
81         rows, err := db.Query("SELECT|people|age,name|")
82         if err != nil {
83                 t.Fatalf("Query: %v", err)
84         }
85         cols, err := rows.Columns()
86         if err != nil {
87                 t.Fatalf("Columns: %v", err)
88         }
89         want := []string{"age", "name"}
90         if !reflect.DeepEqual(cols, want) {
91                 t.Errorf("got %#v; want %#v", cols, want)
92         }
93 }
94
95 func TestQueryRow(t *testing.T) {
96         db := newTestDB(t, "people")
97         defer closeDB(t, db)
98         var name string
99         var age int
100
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)
104         }
105
106         err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
107         if err != nil {
108                 t.Fatalf("age QueryRow+Scan: %v", err)
109         }
110         if name != "Bob" {
111                 t.Errorf("expected name Bob, got %q", name)
112         }
113         if age != 2 {
114                 t.Errorf("expected age 2, got %d", age)
115         }
116
117         err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
118         if err != nil {
119                 t.Fatalf("name QueryRow+Scan: %v", err)
120         }
121         if name != "Alice" {
122                 t.Errorf("expected name Alice, got %q", name)
123         }
124         if age != 1 {
125                 t.Errorf("expected age 1, got %d", age)
126         }
127 }
128
129 func TestStatementErrorAfterClose(t *testing.T) {
130         db := newTestDB(t, "people")
131         defer closeDB(t, db)
132         stmt, err := db.Prepare("SELECT|people|age|name=?")
133         if err != nil {
134                 t.Fatalf("Prepare: %v", err)
135         }
136         err = stmt.Close()
137         if err != nil {
138                 t.Fatalf("Close: %v", err)
139         }
140         var name string
141         err = stmt.QueryRow("foo").Scan(&name)
142         if err == nil {
143                 t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
144         }
145 }
146
147 func TestStatementQueryRow(t *testing.T) {
148         db := newTestDB(t, "people")
149         defer closeDB(t, db)
150         stmt, err := db.Prepare("SELECT|people|age|name=?")
151         if err != nil {
152                 t.Fatalf("Prepare: %v", err)
153         }
154         var age int
155         for n, tt := range []struct {
156                 name string
157                 want int
158         }{
159                 {"Alice", 1},
160                 {"Bob", 2},
161                 {"Chris", 3},
162         } {
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)
167                 }
168         }
169
170 }
171
172 // just a test of fakedb itself
173 func TestBogusPreboundParameters(t *testing.T) {
174         db := newTestDB(t, "foo")
175         defer closeDB(t, db)
176         exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
177         _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
178         if err == nil {
179                 t.Fatalf("expected error")
180         }
181         if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
182                 t.Errorf("unexpected error: %v", err)
183         }
184 }
185
186 func TestExec(t *testing.T) {
187         db := newTestDB(t, "foo")
188         defer closeDB(t, db)
189         exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
190         stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
191         if err != nil {
192                 t.Errorf("Stmt, err = %v, %v", stmt, err)
193         }
194
195         type execTest struct {
196                 args    []interface{}
197                 wantErr string
198         }
199         execTests := []execTest{
200                 // Okay:
201                 {[]interface{}{"Brad", 31}, ""},
202                 {[]interface{}{"Brad", int64(31)}, ""},
203                 {[]interface{}{"Bob", "32"}, ""},
204                 {[]interface{}{7, 9}, ""},
205
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"},
209
210                 // Wrong number of args:
211                 {[]interface{}{}, "sql: expected 2 arguments, got 0"},
212                 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
213         }
214         for n, et := range execTests {
215                 _, err := stmt.Exec(et.args...)
216                 errStr := ""
217                 if err != nil {
218                         errStr = err.Error()
219                 }
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)
223                 }
224         }
225 }
226
227 func TestTxStmt(t *testing.T) {
228         db := newTestDB(t, "")
229         defer closeDB(t, db)
230         exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
231         stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
232         if err != nil {
233                 t.Fatalf("Stmt, err = %v, %v", stmt, err)
234         }
235         tx, err := db.Begin()
236         if err != nil {
237                 t.Fatalf("Begin = %v", err)
238         }
239         _, err = tx.Stmt(stmt).Exec("Bobby", 7)
240         if err != nil {
241                 t.Fatalf("Exec = %v", err)
242         }
243         err = tx.Commit()
244         if err != nil {
245                 t.Fatalf("Commit = %v", err)
246         }
247 }
248
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")
253         closeDB(t, db)
254         for i := 0; i < 2; i++ {
255                 _, err := db.Query("SELECT|people|age,name|")
256                 if err == nil {
257                         t.Fatalf("expected error")
258                 }
259         }
260 }