comparison UnitTests/SQLiteChromium.cpp @ 0:3959d33612cc

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Jul 2012 14:32:22 +0200
parents
children a15e90e5d6fc
comparison
equal deleted inserted replaced
-1:000000000000 0:3959d33612cc
1 #include "gtest/gtest.h"
2
3 #include "../Core/Toolbox.h"
4 #include "../Core/SQLite/Connection.h"
5 #include "../Core/SQLite/Statement.h"
6 #include "../Core/SQLite/Transaction.h"
7
8 #include <sqlite3.h>
9
10 using namespace Palantir;
11
12
13
14 /********************************************************************
15 ** Tests from
16 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/connection_unittest.cc
17 ********************************************************************/
18
19 class SQLConnectionTest : public testing::Test
20 {
21 public:
22 SQLConnectionTest()
23 {
24 }
25
26 virtual ~SQLConnectionTest()
27 {
28 }
29
30 virtual void SetUp()
31 {
32 db_.OpenInMemory();
33 }
34
35 virtual void TearDown()
36 {
37 db_.Close();
38 }
39
40 SQLite::Connection& db()
41 {
42 return db_;
43 }
44
45 private:
46 SQLite::Connection db_;
47 };
48
49
50
51 TEST_F(SQLConnectionTest, Execute)
52 {
53 // Valid statement should return true.
54 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
55 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
56
57 // Invalid statement should fail.
58 ASSERT_EQ(SQLITE_ERROR,
59 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
60 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
61 }
62
63 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) {
64 ASSERT_EQ(SQLITE_OK,
65 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
66 ASSERT_EQ(SQLITE_ERROR,
67 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
68 ASSERT_EQ(SQLITE_ERROR,
69 db().ExecuteAndReturnErrorCode(
70 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
71 }
72
73 TEST_F(SQLConnectionTest, CachedStatement) {
74 SQLite::StatementId id1("foo", 12);
75 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
76 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
77
78 // Create a new cached statement.
79 {
80 SQLite::Statement s(db(), id1, "SELECT a FROM foo");
81 ASSERT_TRUE(s.Step());
82 EXPECT_EQ(12, s.ColumnInt(0));
83 }
84
85 // The statement should be cached still.
86 EXPECT_TRUE(db().HasCachedStatement(id1));
87
88 {
89 // Get the same statement using different SQL. This should ignore our
90 // SQL and use the cached one (so it will be valid).
91 SQLite::Statement s(db(), id1, "something invalid(");
92 ASSERT_TRUE(s.Step());
93 EXPECT_EQ(12, s.ColumnInt(0));
94 }
95
96 // Make sure other statements aren't marked as cached.
97 EXPECT_FALSE(db().HasCachedStatement(SQLITE_FROM_HERE));
98 }
99
100 TEST_F(SQLConnectionTest, IsSQLValidTest) {
101 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
102 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
103 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
104 }
105
106
107
108 TEST_F(SQLConnectionTest, DoesStuffExist) {
109 // Test DoesTableExist.
110 EXPECT_FALSE(db().DoesTableExist("foo"));
111 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
112 EXPECT_TRUE(db().DoesTableExist("foo"));
113
114 // Should be case sensitive.
115 EXPECT_FALSE(db().DoesTableExist("FOO"));
116
117 // Test DoesColumnExist.
118 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
119 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
120
121 // Testing for a column on a nonexistent table.
122 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
123 }
124
125 TEST_F(SQLConnectionTest, GetLastInsertRowId) {
126 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
127
128 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
129
130 // Last insert row ID should be valid.
131 int64_t row = db().GetLastInsertRowId();
132 EXPECT_LT(0, row);
133
134 // It should be the primary key of the row we just inserted.
135 SQLite::Statement s(db(), "SELECT value FROM foo WHERE id=?");
136 s.BindInt64(0, row);
137 ASSERT_TRUE(s.Step());
138 EXPECT_EQ(12, s.ColumnInt(0));
139 }
140
141 TEST_F(SQLConnectionTest, Rollback) {
142 ASSERT_TRUE(db().BeginTransaction());
143 ASSERT_TRUE(db().BeginTransaction());
144 EXPECT_EQ(2, db().GetTransactionNesting());
145 db().RollbackTransaction();
146 EXPECT_FALSE(db().CommitTransaction());
147 EXPECT_TRUE(db().BeginTransaction());
148 }
149
150
151
152
153 /********************************************************************
154 ** Tests from
155 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/statement_unittest.cc
156 ********************************************************************/
157
158 class SQLStatementTest : public SQLConnectionTest
159 {
160 };
161
162
163 TEST_F(SQLStatementTest, Run) {
164 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
165 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
166
167 SQLite::Statement s(db(), "SELECT b FROM foo WHERE a=?");
168 // Stepping it won't work since we haven't bound the value.
169 EXPECT_FALSE(s.Step());
170
171 // Run should fail since this produces output, and we should use Step(). This
172 // gets a bit wonky since sqlite says this is OK so succeeded is set.
173 s.Reset(true);
174 s.BindInt(0, 3);
175 EXPECT_FALSE(s.Run());
176 EXPECT_EQ(SQLITE_ROW, db().GetErrorCode());
177
178 // Resetting it should put it back to the previous state (not runnable).
179 s.Reset(true);
180
181 // Binding and stepping should produce one row.
182 s.BindInt(0, 3);
183 EXPECT_TRUE(s.Step());
184 EXPECT_EQ(12, s.ColumnInt(0));
185 EXPECT_FALSE(s.Step());
186 }
187
188 TEST_F(SQLStatementTest, BasicErrorCallback) {
189 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
190 // Insert in the foo table the primary key. It is an error to insert
191 // something other than an number. This error causes the error callback
192 // handler to be called with SQLITE_MISMATCH as error code.
193 SQLite::Statement s(db(), "INSERT INTO foo (a) VALUES (?)");
194 s.BindCString(0, "bad bad");
195 EXPECT_THROW(s.Run(), PalantirException);
196 }
197
198 TEST_F(SQLStatementTest, Reset) {
199 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
200 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
201 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)"));
202
203 SQLite::Statement s(db(), "SELECT b FROM foo WHERE a = ? ");
204 s.BindInt(0, 3);
205 ASSERT_TRUE(s.Step());
206 EXPECT_EQ(12, s.ColumnInt(0));
207 ASSERT_FALSE(s.Step());
208
209 s.Reset(false);
210 // Verify that we can get all rows again.
211 ASSERT_TRUE(s.Step());
212 EXPECT_EQ(12, s.ColumnInt(0));
213 EXPECT_FALSE(s.Step());
214
215 s.Reset(true);
216 ASSERT_FALSE(s.Step());
217 }
218
219
220
221
222
223
224
225 /********************************************************************
226 ** Tests from
227 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/transaction_unittest.cc
228 ********************************************************************/
229
230 class SQLTransactionTest : public SQLConnectionTest
231 {
232 public:
233 virtual void SetUp()
234 {
235 SQLConnectionTest::SetUp();
236 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
237 }
238
239 // Returns the number of rows in table "foo".
240 int CountFoo()
241 {
242 SQLite::Statement count(db(), "SELECT count(*) FROM foo");
243 count.Step();
244 return count.ColumnInt(0);
245 }
246 };
247
248
249 TEST_F(SQLTransactionTest, Commit) {
250 {
251 SQLite::Transaction t(db());
252 EXPECT_FALSE(t.IsOpen());
253 t.Begin();
254 EXPECT_TRUE(t.IsOpen());
255
256 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
257
258 t.Commit();
259 EXPECT_FALSE(t.IsOpen());
260 }
261
262 EXPECT_EQ(1, CountFoo());
263 }
264
265 TEST_F(SQLTransactionTest, Rollback) {
266 // Test some basic initialization, and that rollback runs when you exit the
267 // scope.
268 {
269 SQLite::Transaction t(db());
270 EXPECT_FALSE(t.IsOpen());
271 t.Begin();
272 EXPECT_TRUE(t.IsOpen());
273
274 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
275 }
276
277 // Nothing should have been committed since it was implicitly rolled back.
278 EXPECT_EQ(0, CountFoo());
279
280 // Test explicit rollback.
281 SQLite::Transaction t2(db());
282 EXPECT_FALSE(t2.IsOpen());
283 t2.Begin();
284
285 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
286 t2.Rollback();
287 EXPECT_FALSE(t2.IsOpen());
288
289 // Nothing should have been committed since it was explicitly rolled back.
290 EXPECT_EQ(0, CountFoo());
291 }
292
293 // Rolling back any part of a transaction should roll back all of them.
294 TEST_F(SQLTransactionTest, NestedRollback) {
295 EXPECT_EQ(0, db().GetTransactionNesting());
296
297 // Outermost transaction.
298 {
299 SQLite::Transaction outer(db());
300 outer.Begin();
301 EXPECT_EQ(1, db().GetTransactionNesting());
302
303 // The first inner one gets committed.
304 {
305 SQLite::Transaction inner1(db());
306 inner1.Begin();
307 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
308 EXPECT_EQ(2, db().GetTransactionNesting());
309
310 inner1.Commit();
311 EXPECT_EQ(1, db().GetTransactionNesting());
312 }
313
314 // One row should have gotten inserted.
315 EXPECT_EQ(1, CountFoo());
316
317 // The second inner one gets rolled back.
318 {
319 SQLite::Transaction inner2(db());
320 inner2.Begin();
321 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
322 EXPECT_EQ(2, db().GetTransactionNesting());
323
324 inner2.Rollback();
325 EXPECT_EQ(1, db().GetTransactionNesting());
326 }
327
328 // A third inner one will fail in Begin since one has already been rolled
329 // back.
330 EXPECT_EQ(1, db().GetTransactionNesting());
331 {
332 SQLite::Transaction inner3(db());
333 EXPECT_THROW(inner3.Begin(), PalantirException);
334 EXPECT_EQ(1, db().GetTransactionNesting());
335 }
336 }
337 EXPECT_EQ(0, db().GetTransactionNesting());
338 EXPECT_EQ(0, CountFoo());
339 }