]>
Commit | Line | Data |
---|---|---|
5e5d088a | 1 | // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. |
2 | // | |
3 | // Use of this source code is governed by an MIT-style | |
4 | // license that can be found in the LICENSE file. | |
6535341d | 5 | |
2d6a60e2 JV |
6 | package sqlite3 |
7 | ||
8 | import ( | |
9 | "database/sql" | |
10 | "io/ioutil" | |
11 | "os" | |
12 | "path" | |
13 | "testing" | |
14 | ) | |
15 | ||
dfec358c | 16 | func TestSimpleError(t *testing.T) { |
ba91ba98 | 17 | e := ErrError.Error() |
18 | if e != "SQL logic error or missing database" { | |
19 | t.Error("wrong error code:" + e) | |
dfec358c | 20 | } |
21 | } | |
22 | ||
72bb737c | 23 | func TestCorruptDbErrors(t *testing.T) { |
2d6a60e2 JV |
24 | dirName, err := ioutil.TempDir("", "sqlite3") |
25 | if err != nil { | |
26 | t.Fatal(err) | |
27 | } | |
28 | defer os.RemoveAll(dirName) | |
29 | ||
30 | dbFileName := path.Join(dirName, "test.db") | |
31 | f, err := os.Create(dbFileName) | |
32 | if err != nil { | |
33 | t.Error(err) | |
34 | } | |
35 | f.Write([]byte{1, 2, 3, 4, 5}) | |
36 | f.Close() | |
37 | ||
38 | db, err := sql.Open("sqlite3", dbFileName) | |
39 | if err == nil { | |
40 | _, err = db.Exec("drop table foo") | |
41 | } | |
e0729751 RK |
42 | |
43 | sqliteErr := err.(Error) | |
44 | if sqliteErr.Code != ErrNotADB { | |
2d6a60e2 JV |
45 | t.Error("wrong error code for corrupted DB") |
46 | } | |
6176b90b | 47 | if err.Error() == "" { |
48 | t.Error("wrong error string for corrupted DB") | |
49 | } | |
2d6a60e2 JV |
50 | db.Close() |
51 | } | |
72bb737c RK |
52 | |
53 | func TestSqlLogicErrors(t *testing.T) { | |
54 | dirName, err := ioutil.TempDir("", "sqlite3") | |
55 | if err != nil { | |
56 | t.Fatal(err) | |
57 | } | |
58 | defer os.RemoveAll(dirName) | |
59 | ||
60 | dbFileName := path.Join(dirName, "test.db") | |
61 | db, err := sql.Open("sqlite3", dbFileName) | |
62 | if err != nil { | |
63 | t.Error(err) | |
64 | } | |
f395aa17 | 65 | defer db.Close() |
72bb737c | 66 | |
f395aa17 | 67 | _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)") |
72bb737c RK |
68 | if err != nil { |
69 | t.Error(err) | |
70 | } | |
71 | ||
72 | const expectedErr = "table Foo already exists" | |
f395aa17 | 73 | _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)") |
72bb737c RK |
74 | if err.Error() != expectedErr { |
75 | t.Errorf("Unexpected error: %s, expected %s", err.Error(), expectedErr) | |
76 | } | |
f395aa17 CM |
77 | |
78 | } | |
79 | ||
80 | func TestExtendedErrorCodes_ForeignKey(t *testing.T) { | |
81 | dirName, err := ioutil.TempDir("", "sqlite3-err") | |
82 | if err != nil { | |
83 | t.Fatal(err) | |
84 | } | |
85 | defer os.RemoveAll(dirName) | |
86 | ||
87 | dbFileName := path.Join(dirName, "test.db") | |
88 | db, err := sql.Open("sqlite3", dbFileName) | |
89 | if err != nil { | |
90 | t.Error(err) | |
91 | } | |
92 | defer db.Close() | |
93 | ||
94 | _, err = db.Exec("PRAGMA foreign_keys=ON;") | |
95 | if err != nil { | |
96 | t.Errorf("PRAGMA foreign_keys=ON: %v", err) | |
97 | } | |
98 | ||
99 | _, err = db.Exec(`CREATE TABLE Foo ( | |
100 | id INTEGER PRIMARY KEY AUTOINCREMENT, | |
101 | value INTEGER NOT NULL, | |
102 | ref INTEGER NULL REFERENCES Foo (id), | |
103 | UNIQUE(value) | |
104 | );`) | |
105 | if err != nil { | |
106 | t.Error(err) | |
107 | } | |
108 | ||
109 | _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (100, 100);") | |
110 | if err == nil { | |
111 | t.Error("No error!") | |
112 | } else { | |
113 | sqliteErr := err.(Error) | |
114 | if sqliteErr.Code != ErrConstraint { | |
115 | t.Errorf("Wrong basic error code: %d != %d", | |
116 | sqliteErr.Code, ErrConstraint) | |
117 | } | |
118 | if sqliteErr.ExtendedCode != ErrConstraintForeignKey { | |
119 | t.Errorf("Wrong extended error code: %d != %d", | |
120 | sqliteErr.ExtendedCode, ErrConstraintForeignKey) | |
121 | } | |
122 | } | |
123 | ||
124 | } | |
125 | ||
126 | func TestExtendedErrorCodes_NotNull(t *testing.T) { | |
127 | dirName, err := ioutil.TempDir("", "sqlite3-err") | |
128 | if err != nil { | |
129 | t.Fatal(err) | |
130 | } | |
131 | defer os.RemoveAll(dirName) | |
132 | ||
133 | dbFileName := path.Join(dirName, "test.db") | |
134 | db, err := sql.Open("sqlite3", dbFileName) | |
135 | if err != nil { | |
136 | t.Error(err) | |
137 | } | |
138 | defer db.Close() | |
139 | ||
140 | _, err = db.Exec("PRAGMA foreign_keys=ON;") | |
141 | if err != nil { | |
142 | t.Errorf("PRAGMA foreign_keys=ON: %v", err) | |
143 | } | |
144 | ||
145 | _, err = db.Exec(`CREATE TABLE Foo ( | |
146 | id INTEGER PRIMARY KEY AUTOINCREMENT, | |
147 | value INTEGER NOT NULL, | |
148 | ref INTEGER NULL REFERENCES Foo (id), | |
149 | UNIQUE(value) | |
150 | );`) | |
151 | if err != nil { | |
152 | t.Error(err) | |
153 | } | |
154 | ||
155 | res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);") | |
156 | if err != nil { | |
157 | t.Fatalf("Creating first row: %v", err) | |
158 | } | |
159 | ||
160 | id, err := res.LastInsertId() | |
161 | if err != nil { | |
162 | t.Fatalf("Retrieving last insert id: %v", err) | |
163 | } | |
164 | ||
165 | _, err = db.Exec("INSERT INTO Foo (ref) VALUES (?);", id) | |
166 | if err == nil { | |
167 | t.Error("No error!") | |
168 | } else { | |
169 | sqliteErr := err.(Error) | |
170 | if sqliteErr.Code != ErrConstraint { | |
171 | t.Errorf("Wrong basic error code: %d != %d", | |
172 | sqliteErr.Code, ErrConstraint) | |
173 | } | |
174 | if sqliteErr.ExtendedCode != ErrConstraintNotNull { | |
175 | t.Errorf("Wrong extended error code: %d != %d", | |
176 | sqliteErr.ExtendedCode, ErrConstraintNotNull) | |
177 | } | |
178 | } | |
179 | ||
180 | } | |
181 | ||
182 | func TestExtendedErrorCodes_Unique(t *testing.T) { | |
183 | dirName, err := ioutil.TempDir("", "sqlite3-err") | |
184 | if err != nil { | |
185 | t.Fatal(err) | |
186 | } | |
187 | defer os.RemoveAll(dirName) | |
188 | ||
189 | dbFileName := path.Join(dirName, "test.db") | |
190 | db, err := sql.Open("sqlite3", dbFileName) | |
191 | if err != nil { | |
192 | t.Error(err) | |
193 | } | |
194 | defer db.Close() | |
195 | ||
196 | _, err = db.Exec("PRAGMA foreign_keys=ON;") | |
197 | if err != nil { | |
198 | t.Errorf("PRAGMA foreign_keys=ON: %v", err) | |
199 | } | |
200 | ||
201 | _, err = db.Exec(`CREATE TABLE Foo ( | |
202 | id INTEGER PRIMARY KEY AUTOINCREMENT, | |
203 | value INTEGER NOT NULL, | |
204 | ref INTEGER NULL REFERENCES Foo (id), | |
205 | UNIQUE(value) | |
206 | );`) | |
207 | if err != nil { | |
208 | t.Error(err) | |
209 | } | |
210 | ||
211 | res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);") | |
212 | if err != nil { | |
213 | t.Fatalf("Creating first row: %v", err) | |
214 | } | |
215 | ||
216 | id, err := res.LastInsertId() | |
217 | if err != nil { | |
218 | t.Fatalf("Retrieving last insert id: %v", err) | |
219 | } | |
220 | ||
221 | _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (?, 100);", id) | |
222 | if err == nil { | |
223 | t.Error("No error!") | |
224 | } else { | |
225 | sqliteErr := err.(Error) | |
226 | if sqliteErr.Code != ErrConstraint { | |
227 | t.Errorf("Wrong basic error code: %d != %d", | |
228 | sqliteErr.Code, ErrConstraint) | |
229 | } | |
230 | if sqliteErr.ExtendedCode != ErrConstraintUnique { | |
231 | t.Errorf("Wrong extended error code: %d != %d", | |
232 | sqliteErr.ExtendedCode, ErrConstraintUnique) | |
233 | } | |
a528a308 | 234 | extended := sqliteErr.Code.Extend(3).Error() |
235 | expected := "constraint failed" | |
236 | if extended != expected { | |
237 | t.Errorf("Wrong basic error code: %q != %q", | |
238 | extended, expected) | |
239 | } | |
f395aa17 CM |
240 | } |
241 | ||
72bb737c | 242 | } |