Mercurial > hg > orthanc
comparison UnitTests/SQLiteChromium.cpp @ 138:f333c0398f6e
some hiding
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Oct 2012 16:53:03 +0200 |
parents | f1d0470ff334 |
children |
comparison
equal
deleted
inserted
replaced
137:0e97abc7b950 | 138:f333c0398f6e |
---|---|
5 #include "../Core/SQLite/Statement.h" | 5 #include "../Core/SQLite/Statement.h" |
6 #include "../Core/SQLite/Transaction.h" | 6 #include "../Core/SQLite/Transaction.h" |
7 | 7 |
8 #include <sqlite3.h> | 8 #include <sqlite3.h> |
9 | 9 |
10 | |
10 using namespace Orthanc; | 11 using namespace Orthanc; |
11 | 12 using namespace Orthanc::SQLite; |
12 | 13 |
13 | 14 |
14 /******************************************************************** | 15 /******************************************************************** |
15 ** Tests from | 16 ** Tests from |
16 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/connection_unittest.cc | 17 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/connection_unittest.cc |
35 virtual void TearDown() | 36 virtual void TearDown() |
36 { | 37 { |
37 db_.Close(); | 38 db_.Close(); |
38 } | 39 } |
39 | 40 |
40 SQLite::Connection& db() | 41 Connection& db() |
41 { | 42 { |
42 return db_; | 43 return db_; |
43 } | 44 } |
44 | 45 |
45 private: | 46 private: |
46 SQLite::Connection db_; | 47 Connection db_; |
47 }; | 48 }; |
48 | 49 |
49 | 50 |
50 | 51 |
51 TEST_F(SQLConnectionTest, Execute) | 52 TEST_F(SQLConnectionTest, Execute) |
65 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)")); | 66 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)")); |
66 ASSERT_EQ(SQLITE_ERROR, | 67 ASSERT_EQ(SQLITE_ERROR, |
67 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE")); | 68 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE")); |
68 ASSERT_EQ(SQLITE_ERROR, | 69 ASSERT_EQ(SQLITE_ERROR, |
69 db().ExecuteAndReturnErrorCode( | 70 db().ExecuteAndReturnErrorCode( |
70 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)")); | 71 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)")); |
71 } | 72 } |
72 | 73 |
73 TEST_F(SQLConnectionTest, CachedStatement) { | 74 TEST_F(SQLConnectionTest, CachedStatement) { |
74 SQLite::StatementId id1("foo", 12); | 75 StatementId id1("foo", 12); |
75 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | 76 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); |
76 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)")); | 77 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)")); |
77 | 78 |
78 // Create a new cached statement. | 79 // Create a new cached statement. |
79 { | 80 { |
80 SQLite::Statement s(db(), id1, "SELECT a FROM foo"); | 81 Statement s(db(), id1, "SELECT a FROM foo"); |
81 ASSERT_TRUE(s.Step()); | 82 ASSERT_TRUE(s.Step()); |
82 EXPECT_EQ(12, s.ColumnInt(0)); | 83 EXPECT_EQ(12, s.ColumnInt(0)); |
83 } | 84 } |
84 | 85 |
85 // The statement should be cached still. | 86 // The statement should be cached still. |
86 EXPECT_TRUE(db().HasCachedStatement(id1)); | 87 EXPECT_TRUE(db().HasCachedStatement(id1)); |
87 | 88 |
88 { | 89 { |
89 // Get the same statement using different SQL. This should ignore our | 90 // Get the same statement using different SQL. This should ignore our |
90 // SQL and use the cached one (so it will be valid). | 91 // SQL and use the cached one (so it will be valid). |
91 SQLite::Statement s(db(), id1, "something invalid("); | 92 Statement s(db(), id1, "something invalid("); |
92 ASSERT_TRUE(s.Step()); | 93 ASSERT_TRUE(s.Step()); |
93 EXPECT_EQ(12, s.ColumnInt(0)); | 94 EXPECT_EQ(12, s.ColumnInt(0)); |
94 } | 95 } |
95 | 96 |
96 // Make sure other statements aren't marked as cached. | 97 // Make sure other statements aren't marked as cached. |
130 // Last insert row ID should be valid. | 131 // Last insert row ID should be valid. |
131 int64_t row = db().GetLastInsertRowId(); | 132 int64_t row = db().GetLastInsertRowId(); |
132 EXPECT_LT(0, row); | 133 EXPECT_LT(0, row); |
133 | 134 |
134 // It should be the primary key of the row we just inserted. | 135 // It should be the primary key of the row we just inserted. |
135 SQLite::Statement s(db(), "SELECT value FROM foo WHERE id=?"); | 136 Statement s(db(), "SELECT value FROM foo WHERE id=?"); |
136 s.BindInt64(0, row); | 137 s.BindInt64(0, row); |
137 ASSERT_TRUE(s.Step()); | 138 ASSERT_TRUE(s.Step()); |
138 EXPECT_EQ(12, s.ColumnInt(0)); | 139 EXPECT_EQ(12, s.ColumnInt(0)); |
139 } | 140 } |
140 | 141 |
153 /******************************************************************** | 154 /******************************************************************** |
154 ** Tests from | 155 ** Tests from |
155 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/statement_unittest.cc | 156 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/statement_unittest.cc |
156 ********************************************************************/ | 157 ********************************************************************/ |
157 | 158 |
158 class SQLStatementTest : public SQLConnectionTest | 159 namespace Orthanc |
159 { | 160 { |
160 }; | 161 namespace SQLite |
161 | 162 { |
162 | 163 class SQLStatementTest : public SQLConnectionTest |
163 TEST_F(SQLStatementTest, Run) { | 164 { |
164 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | 165 }; |
165 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)")); | 166 |
166 | 167 TEST_F(SQLStatementTest, Run) { |
167 SQLite::Statement s(db(), "SELECT b FROM foo WHERE a=?"); | 168 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); |
168 // Stepping it won't work since we haven't bound the value. | 169 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)")); |
169 EXPECT_FALSE(s.Step()); | 170 |
170 | 171 Statement s(db(), "SELECT b FROM foo WHERE a=?"); |
171 // Run should fail since this produces output, and we should use Step(). This | 172 // Stepping it won't work since we haven't bound the value. |
172 // gets a bit wonky since sqlite says this is OK so succeeded is set. | 173 EXPECT_FALSE(s.Step()); |
173 s.Reset(true); | 174 |
174 s.BindInt(0, 3); | 175 // Run should fail since this produces output, and we should use Step(). This |
175 EXPECT_FALSE(s.Run()); | 176 // gets a bit wonky since sqlite says this is OK so succeeded is set. |
176 EXPECT_EQ(SQLITE_ROW, db().GetErrorCode()); | 177 s.Reset(true); |
177 | 178 s.BindInt(0, 3); |
178 // Resetting it should put it back to the previous state (not runnable). | 179 EXPECT_FALSE(s.Run()); |
179 s.Reset(true); | 180 EXPECT_EQ(SQLITE_ROW, db().GetErrorCode()); |
180 | 181 |
181 // Binding and stepping should produce one row. | 182 // Resetting it should put it back to the previous state (not runnable). |
182 s.BindInt(0, 3); | 183 s.Reset(true); |
183 EXPECT_TRUE(s.Step()); | 184 |
184 EXPECT_EQ(12, s.ColumnInt(0)); | 185 // Binding and stepping should produce one row. |
185 EXPECT_FALSE(s.Step()); | 186 s.BindInt(0, 3); |
186 } | 187 EXPECT_TRUE(s.Step()); |
187 | 188 EXPECT_EQ(12, s.ColumnInt(0)); |
188 TEST_F(SQLStatementTest, BasicErrorCallback) { | 189 EXPECT_FALSE(s.Step()); |
189 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)")); | 190 } |
190 // Insert in the foo table the primary key. It is an error to insert | 191 |
191 // something other than an number. This error causes the error callback | 192 TEST_F(SQLStatementTest, BasicErrorCallback) { |
192 // handler to be called with SQLITE_MISMATCH as error code. | 193 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)")); |
193 SQLite::Statement s(db(), "INSERT INTO foo (a) VALUES (?)"); | 194 // Insert in the foo table the primary key. It is an error to insert |
194 s.BindCString(0, "bad bad"); | 195 // something other than an number. This error causes the error callback |
195 EXPECT_THROW(s.Run(), OrthancException); | 196 // handler to be called with SQLITE_MISMATCH as error code. |
196 } | 197 Statement s(db(), "INSERT INTO foo (a) VALUES (?)"); |
197 | 198 s.BindCString(0, "bad bad"); |
198 TEST_F(SQLStatementTest, Reset) { | 199 EXPECT_THROW(s.Run(), OrthancException); |
199 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); | 200 } |
200 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)")); | 201 |
201 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)")); | 202 TEST_F(SQLStatementTest, Reset) { |
202 | 203 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); |
203 SQLite::Statement s(db(), "SELECT b FROM foo WHERE a = ? "); | 204 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)")); |
204 s.BindInt(0, 3); | 205 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)")); |
205 ASSERT_TRUE(s.Step()); | 206 |
206 EXPECT_EQ(12, s.ColumnInt(0)); | 207 Statement s(db(), "SELECT b FROM foo WHERE a = ? "); |
207 ASSERT_FALSE(s.Step()); | 208 s.BindInt(0, 3); |
208 | 209 ASSERT_TRUE(s.Step()); |
209 s.Reset(false); | 210 EXPECT_EQ(12, s.ColumnInt(0)); |
210 // Verify that we can get all rows again. | 211 ASSERT_FALSE(s.Step()); |
211 ASSERT_TRUE(s.Step()); | 212 |
212 EXPECT_EQ(12, s.ColumnInt(0)); | 213 s.Reset(false); |
213 EXPECT_FALSE(s.Step()); | 214 // Verify that we can get all rows again. |
214 | 215 ASSERT_TRUE(s.Step()); |
215 s.Reset(true); | 216 EXPECT_EQ(12, s.ColumnInt(0)); |
216 ASSERT_FALSE(s.Step()); | 217 EXPECT_FALSE(s.Step()); |
217 } | 218 |
218 | 219 s.Reset(true); |
220 ASSERT_FALSE(s.Step()); | |
221 } | |
222 } | |
223 } | |
219 | 224 |
220 | 225 |
221 | 226 |
222 | 227 |
223 | 228 |
237 } | 242 } |
238 | 243 |
239 // Returns the number of rows in table "foo". | 244 // Returns the number of rows in table "foo". |
240 int CountFoo() | 245 int CountFoo() |
241 { | 246 { |
242 SQLite::Statement count(db(), "SELECT count(*) FROM foo"); | 247 Statement count(db(), "SELECT count(*) FROM foo"); |
243 count.Step(); | 248 count.Step(); |
244 return count.ColumnInt(0); | 249 return count.ColumnInt(0); |
245 } | 250 } |
246 }; | 251 }; |
247 | 252 |
248 | 253 |
249 TEST_F(SQLTransactionTest, Commit) { | 254 TEST_F(SQLTransactionTest, Commit) { |
250 { | 255 { |
251 SQLite::Transaction t(db()); | 256 Transaction t(db()); |
252 EXPECT_FALSE(t.IsOpen()); | 257 EXPECT_FALSE(t.IsOpen()); |
253 t.Begin(); | 258 t.Begin(); |
254 EXPECT_TRUE(t.IsOpen()); | 259 EXPECT_TRUE(t.IsOpen()); |
255 | 260 |
256 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); | 261 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); |
264 | 269 |
265 TEST_F(SQLTransactionTest, Rollback) { | 270 TEST_F(SQLTransactionTest, Rollback) { |
266 // Test some basic initialization, and that rollback runs when you exit the | 271 // Test some basic initialization, and that rollback runs when you exit the |
267 // scope. | 272 // scope. |
268 { | 273 { |
269 SQLite::Transaction t(db()); | 274 Transaction t(db()); |
270 EXPECT_FALSE(t.IsOpen()); | 275 EXPECT_FALSE(t.IsOpen()); |
271 t.Begin(); | 276 t.Begin(); |
272 EXPECT_TRUE(t.IsOpen()); | 277 EXPECT_TRUE(t.IsOpen()); |
273 | 278 |
274 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); | 279 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); |
276 | 281 |
277 // Nothing should have been committed since it was implicitly rolled back. | 282 // Nothing should have been committed since it was implicitly rolled back. |
278 EXPECT_EQ(0, CountFoo()); | 283 EXPECT_EQ(0, CountFoo()); |
279 | 284 |
280 // Test explicit rollback. | 285 // Test explicit rollback. |
281 SQLite::Transaction t2(db()); | 286 Transaction t2(db()); |
282 EXPECT_FALSE(t2.IsOpen()); | 287 EXPECT_FALSE(t2.IsOpen()); |
283 t2.Begin(); | 288 t2.Begin(); |
284 | 289 |
285 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); | 290 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); |
286 t2.Rollback(); | 291 t2.Rollback(); |
294 TEST_F(SQLTransactionTest, NestedRollback) { | 299 TEST_F(SQLTransactionTest, NestedRollback) { |
295 EXPECT_EQ(0, db().GetTransactionNesting()); | 300 EXPECT_EQ(0, db().GetTransactionNesting()); |
296 | 301 |
297 // Outermost transaction. | 302 // Outermost transaction. |
298 { | 303 { |
299 SQLite::Transaction outer(db()); | 304 Transaction outer(db()); |
300 outer.Begin(); | 305 outer.Begin(); |
301 EXPECT_EQ(1, db().GetTransactionNesting()); | 306 EXPECT_EQ(1, db().GetTransactionNesting()); |
302 | 307 |
303 // The first inner one gets committed. | 308 // The first inner one gets committed. |
304 { | 309 { |
305 SQLite::Transaction inner1(db()); | 310 Transaction inner1(db()); |
306 inner1.Begin(); | 311 inner1.Begin(); |
307 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); | 312 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); |
308 EXPECT_EQ(2, db().GetTransactionNesting()); | 313 EXPECT_EQ(2, db().GetTransactionNesting()); |
309 | 314 |
310 inner1.Commit(); | 315 inner1.Commit(); |
314 // One row should have gotten inserted. | 319 // One row should have gotten inserted. |
315 EXPECT_EQ(1, CountFoo()); | 320 EXPECT_EQ(1, CountFoo()); |
316 | 321 |
317 // The second inner one gets rolled back. | 322 // The second inner one gets rolled back. |
318 { | 323 { |
319 SQLite::Transaction inner2(db()); | 324 Transaction inner2(db()); |
320 inner2.Begin(); | 325 inner2.Begin(); |
321 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); | 326 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)")); |
322 EXPECT_EQ(2, db().GetTransactionNesting()); | 327 EXPECT_EQ(2, db().GetTransactionNesting()); |
323 | 328 |
324 inner2.Rollback(); | 329 inner2.Rollback(); |
327 | 332 |
328 // A third inner one will fail in Begin since one has already been rolled | 333 // A third inner one will fail in Begin since one has already been rolled |
329 // back. | 334 // back. |
330 EXPECT_EQ(1, db().GetTransactionNesting()); | 335 EXPECT_EQ(1, db().GetTransactionNesting()); |
331 { | 336 { |
332 SQLite::Transaction inner3(db()); | 337 Transaction inner3(db()); |
333 EXPECT_THROW(inner3.Begin(), OrthancException); | 338 EXPECT_THROW(inner3.Begin(), OrthancException); |
334 EXPECT_EQ(1, db().GetTransactionNesting()); | 339 EXPECT_EQ(1, db().GetTransactionNesting()); |
335 } | 340 } |
336 } | 341 } |
337 EXPECT_EQ(0, db().GetTransactionNesting()); | 342 EXPECT_EQ(0, db().GetTransactionNesting()); |