storage/test/test_asyncStatementExecution_transaction.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:2f907d10106e
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
3
4 #include "storage_test_harness.h"
5
6 #include "nsIEventTarget.h"
7 #include "mozStorageConnection.h"
8
9 #include "sqlite3.h"
10
11 using namespace mozilla;
12 using namespace mozilla::storage;
13
14 ////////////////////////////////////////////////////////////////////////////////
15 //// Helpers
16
17 /**
18 * Commit hook to detect transactions.
19 *
20 * @param aArg
21 * An integer pointer that will be incremented for each commit.
22 */
23 int commit_hook(void *aArg)
24 {
25 int *arg = static_cast<int *>(aArg);
26 (*arg)++;
27 return 0;
28 }
29
30 /**
31 * Executes the passed-in statements and checks if a transaction is created.
32 * When done statements are finalized and database connection is closed.
33 *
34 * @param aDB
35 * The database connection.
36 * @param aStmts
37 * Vector of statements.
38 * @param aStmtsLen
39 * Number of statements.
40 * @param aTransactionExpected
41 * Whether a transaction is expected or not.
42 */
43 void
44 check_transaction(mozIStorageConnection *aDB,
45 mozIStorageBaseStatement **aStmts,
46 uint32_t aStmtsLen,
47 bool aTransactionExpected)
48 {
49 // -- install a transaction commit hook.
50 int commit = 0;
51 static_cast<Connection *>(aDB)->setCommitHook(commit_hook, &commit);
52
53 nsRefPtr<AsyncStatementSpinner> asyncSpin(new AsyncStatementSpinner());
54 nsCOMPtr<mozIStoragePendingStatement> asyncPend;
55 do_check_success(aDB->ExecuteAsync(aStmts, aStmtsLen, asyncSpin,
56 getter_AddRefs(asyncPend)));
57 do_check_true(asyncPend);
58
59 // -- complete the execution
60 asyncSpin->SpinUntilCompleted();
61
62 // -- uninstall the transaction commit hook.
63 static_cast<Connection *>(aDB)->setCommitHook(nullptr);
64
65 // -- check transaction
66 do_check_eq(aTransactionExpected, !!commit);
67
68 // -- check that only one transaction was created.
69 if (aTransactionExpected) {
70 do_check_eq(1, commit);
71 }
72
73 // -- cleanup
74 for (uint32_t i = 0; i < aStmtsLen; ++i) {
75 aStmts[i]->Finalize();
76 }
77 blocking_async_close(aDB);
78 }
79
80 ////////////////////////////////////////////////////////////////////////////////
81 //// Tests
82
83 /**
84 * Test that executing multiple readonly AsyncStatements doesn't create a
85 * transaction.
86 */
87 void
88 test_MultipleAsyncReadStatements()
89 {
90 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
91
92 // -- create statements and execute them
93 nsCOMPtr<mozIStorageAsyncStatement> stmt1;
94 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
95 "SELECT * FROM sqlite_master"
96 ), getter_AddRefs(stmt1));
97
98 nsCOMPtr<mozIStorageAsyncStatement> stmt2;
99 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
100 "SELECT * FROM sqlite_master"
101 ), getter_AddRefs(stmt2));
102
103 mozIStorageBaseStatement *stmts[] = {
104 stmt1,
105 stmt2,
106 };
107
108 check_transaction(db, stmts, ArrayLength(stmts), false);
109 }
110
111 /**
112 * Test that executing multiple readonly Statements doesn't create a
113 * transaction.
114 */
115 void
116 test_MultipleReadStatements()
117 {
118 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
119
120 // -- create statements and execute them
121 nsCOMPtr<mozIStorageStatement> stmt1;
122 db->CreateStatement(NS_LITERAL_CSTRING(
123 "SELECT * FROM sqlite_master"
124 ), getter_AddRefs(stmt1));
125
126 nsCOMPtr<mozIStorageStatement> stmt2;
127 db->CreateStatement(NS_LITERAL_CSTRING(
128 "SELECT * FROM sqlite_master"
129 ), getter_AddRefs(stmt2));
130
131 mozIStorageBaseStatement *stmts[] = {
132 stmt1,
133 stmt2,
134 };
135
136 check_transaction(db, stmts, ArrayLength(stmts), false);
137 }
138
139 /**
140 * Test that executing multiple AsyncStatements causing writes creates a
141 * transaction.
142 */
143 void
144 test_MultipleAsyncReadWriteStatements()
145 {
146 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
147
148 // -- create statements and execute them
149 nsCOMPtr<mozIStorageAsyncStatement> stmt1;
150 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
151 "SELECT * FROM sqlite_master"
152 ), getter_AddRefs(stmt1));
153
154 nsCOMPtr<mozIStorageAsyncStatement> stmt2;
155 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
156 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
157 ), getter_AddRefs(stmt2));
158
159 mozIStorageBaseStatement *stmts[] = {
160 stmt1,
161 stmt2,
162 };
163
164 check_transaction(db, stmts, ArrayLength(stmts), true);
165 }
166
167 /**
168 * Test that executing multiple Statements causing writes creates a transaction.
169 */
170 void
171 test_MultipleReadWriteStatements()
172 {
173 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
174
175 // -- create statements and execute them
176 nsCOMPtr<mozIStorageStatement> stmt1;
177 db->CreateStatement(NS_LITERAL_CSTRING(
178 "SELECT * FROM sqlite_master"
179 ), getter_AddRefs(stmt1));
180
181 nsCOMPtr<mozIStorageStatement> stmt2;
182 db->CreateStatement(NS_LITERAL_CSTRING(
183 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
184 ), getter_AddRefs(stmt2));
185
186 mozIStorageBaseStatement *stmts[] = {
187 stmt1,
188 stmt2,
189 };
190
191 check_transaction(db, stmts, ArrayLength(stmts), true);
192 }
193
194 /**
195 * Test that executing multiple AsyncStatements causing writes creates a
196 * single transaction.
197 */
198 void
199 test_MultipleAsyncWriteStatements()
200 {
201 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
202
203 // -- create statements and execute them
204 nsCOMPtr<mozIStorageAsyncStatement> stmt1;
205 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
206 "CREATE TABLE test1 (id INTEGER PRIMARY KEY)"
207 ), getter_AddRefs(stmt1));
208
209 nsCOMPtr<mozIStorageAsyncStatement> stmt2;
210 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
211 "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
212 ), getter_AddRefs(stmt2));
213
214 mozIStorageBaseStatement *stmts[] = {
215 stmt1,
216 stmt2,
217 };
218
219 check_transaction(db, stmts, ArrayLength(stmts), true);
220 }
221
222 /**
223 * Test that executing multiple Statements causing writes creates a
224 * single transaction.
225 */
226 void
227 test_MultipleWriteStatements()
228 {
229 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
230
231 // -- create statements and execute them
232 nsCOMPtr<mozIStorageStatement> stmt1;
233 db->CreateStatement(NS_LITERAL_CSTRING(
234 "CREATE TABLE test1 (id INTEGER PRIMARY KEY)"
235 ), getter_AddRefs(stmt1));
236
237 nsCOMPtr<mozIStorageStatement> stmt2;
238 db->CreateStatement(NS_LITERAL_CSTRING(
239 "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
240 ), getter_AddRefs(stmt2));
241
242 mozIStorageBaseStatement *stmts[] = {
243 stmt1,
244 stmt2,
245 };
246
247 check_transaction(db, stmts, ArrayLength(stmts), true);
248 }
249
250 /**
251 * Test that executing a single read-only AsyncStatement doesn't create a
252 * transaction.
253 */
254 void
255 test_SingleAsyncReadStatement()
256 {
257 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
258
259 // -- create statements and execute them
260 nsCOMPtr<mozIStorageAsyncStatement> stmt;
261 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
262 "SELECT * FROM sqlite_master"
263 ), getter_AddRefs(stmt));
264
265 mozIStorageBaseStatement *stmts[] = {
266 stmt,
267 };
268
269 check_transaction(db, stmts, ArrayLength(stmts), false);
270 }
271
272 /**
273 * Test that executing a single read-only Statement doesn't create a
274 * transaction.
275 */
276 void
277 test_SingleReadStatement()
278 {
279 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
280
281 // -- create statements and execute them
282 nsCOMPtr<mozIStorageStatement> stmt;
283 db->CreateStatement(NS_LITERAL_CSTRING(
284 "SELECT * FROM sqlite_master"
285 ), getter_AddRefs(stmt));
286
287 mozIStorageBaseStatement *stmts[] = {
288 stmt,
289 };
290
291 check_transaction(db, stmts, ArrayLength(stmts), false);
292 }
293
294 /**
295 * Test that executing a single AsyncStatement causing writes creates a
296 * transaction.
297 */
298 void
299 test_SingleAsyncWriteStatement()
300 {
301 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
302
303 // -- create statements and execute them
304 nsCOMPtr<mozIStorageAsyncStatement> stmt;
305 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
306 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
307 ), getter_AddRefs(stmt));
308
309 mozIStorageBaseStatement *stmts[] = {
310 stmt,
311 };
312
313 check_transaction(db, stmts, ArrayLength(stmts), true);
314 }
315
316 /**
317 * Test that executing a single Statement causing writes creates a transaction.
318 */
319 void
320 test_SingleWriteStatement()
321 {
322 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
323
324 // -- create statements and execute them
325 nsCOMPtr<mozIStorageStatement> stmt;
326 db->CreateStatement(NS_LITERAL_CSTRING(
327 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
328 ), getter_AddRefs(stmt));
329
330 mozIStorageBaseStatement *stmts[] = {
331 stmt,
332 };
333
334 check_transaction(db, stmts, ArrayLength(stmts), true);
335 }
336
337 /**
338 * Test that executing a single read-only AsyncStatement with multiple params
339 * doesn't create a transaction.
340 */
341 void
342 test_MultipleParamsAsyncReadStatement()
343 {
344 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
345
346 // -- create statements and execute them
347 nsCOMPtr<mozIStorageAsyncStatement> stmt;
348 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
349 "SELECT :param FROM sqlite_master"
350 ), getter_AddRefs(stmt));
351
352 // -- bind multiple BindingParams
353 nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
354 stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
355 for (int32_t i = 0; i < 2; i++) {
356 nsCOMPtr<mozIStorageBindingParams> params;
357 paramsArray->NewBindingParams(getter_AddRefs(params));
358 params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
359 paramsArray->AddParams(params);
360 }
361 stmt->BindParameters(paramsArray);
362 paramsArray = nullptr;
363
364 mozIStorageBaseStatement *stmts[] = {
365 stmt,
366 };
367
368 check_transaction(db, stmts, ArrayLength(stmts), false);
369 }
370
371 /**
372 * Test that executing a single read-only Statement with multiple params
373 * doesn't create a transaction.
374 */
375 void
376 test_MultipleParamsReadStatement()
377 {
378 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
379
380 // -- create statements and execute them
381 nsCOMPtr<mozIStorageStatement> stmt;
382 db->CreateStatement(NS_LITERAL_CSTRING(
383 "SELECT :param FROM sqlite_master"
384 ), getter_AddRefs(stmt));
385
386 // -- bind multiple BindingParams
387 nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
388 stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
389 for (int32_t i = 0; i < 2; i++) {
390 nsCOMPtr<mozIStorageBindingParams> params;
391 paramsArray->NewBindingParams(getter_AddRefs(params));
392 params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
393 paramsArray->AddParams(params);
394 }
395 stmt->BindParameters(paramsArray);
396 paramsArray = nullptr;
397
398 mozIStorageBaseStatement *stmts[] = {
399 stmt,
400 };
401
402 check_transaction(db, stmts, ArrayLength(stmts), false);
403 }
404
405 /**
406 * Test that executing a single write AsyncStatement with multiple params
407 * creates a transaction.
408 */
409 void
410 test_MultipleParamsAsyncWriteStatement()
411 {
412 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
413
414 // -- create a table for writes
415 nsCOMPtr<mozIStorageStatement> tableStmt;
416 db->CreateStatement(NS_LITERAL_CSTRING(
417 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
418 ), getter_AddRefs(tableStmt));
419 tableStmt->Execute();
420 tableStmt->Finalize();
421
422 // -- create statements and execute them
423 nsCOMPtr<mozIStorageAsyncStatement> stmt;
424 db->CreateAsyncStatement(NS_LITERAL_CSTRING(
425 "DELETE FROM test WHERE id = :param"
426 ), getter_AddRefs(stmt));
427
428 // -- bind multiple BindingParams
429 nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
430 stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
431 for (int32_t i = 0; i < 2; i++) {
432 nsCOMPtr<mozIStorageBindingParams> params;
433 paramsArray->NewBindingParams(getter_AddRefs(params));
434 params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
435 paramsArray->AddParams(params);
436 }
437 stmt->BindParameters(paramsArray);
438 paramsArray = nullptr;
439
440 mozIStorageBaseStatement *stmts[] = {
441 stmt,
442 };
443
444 check_transaction(db, stmts, ArrayLength(stmts), true);
445 }
446
447 /**
448 * Test that executing a single write Statement with multiple params
449 * creates a transaction.
450 */
451 void
452 test_MultipleParamsWriteStatement()
453 {
454 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
455
456 // -- create a table for writes
457 nsCOMPtr<mozIStorageStatement> tableStmt;
458 db->CreateStatement(NS_LITERAL_CSTRING(
459 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
460 ), getter_AddRefs(tableStmt));
461 tableStmt->Execute();
462 tableStmt->Finalize();
463
464 // -- create statements and execute them
465 nsCOMPtr<mozIStorageStatement> stmt;
466 db->CreateStatement(NS_LITERAL_CSTRING(
467 "DELETE FROM test WHERE id = :param"
468 ), getter_AddRefs(stmt));
469
470 // -- bind multiple BindingParams
471 nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
472 stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
473 for (int32_t i = 0; i < 2; i++) {
474 nsCOMPtr<mozIStorageBindingParams> params;
475 paramsArray->NewBindingParams(getter_AddRefs(params));
476 params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
477 paramsArray->AddParams(params);
478 }
479 stmt->BindParameters(paramsArray);
480 paramsArray = nullptr;
481
482 mozIStorageBaseStatement *stmts[] = {
483 stmt,
484 };
485
486 check_transaction(db, stmts, ArrayLength(stmts), true);
487 }
488
489 void (*gTests[])(void) = {
490 test_MultipleAsyncReadStatements,
491 test_MultipleReadStatements,
492 test_MultipleAsyncReadWriteStatements,
493 test_MultipleReadWriteStatements,
494 test_MultipleAsyncWriteStatements,
495 test_MultipleWriteStatements,
496 test_SingleAsyncReadStatement,
497 test_SingleReadStatement,
498 test_SingleAsyncWriteStatement,
499 test_SingleWriteStatement,
500 test_MultipleParamsAsyncReadStatement,
501 test_MultipleParamsReadStatement,
502 test_MultipleParamsAsyncWriteStatement,
503 test_MultipleParamsWriteStatement,
504 };
505
506 const char *file = __FILE__;
507 #define TEST_NAME "async statement execution transaction"
508 #define TEST_FILE file
509 #include "storage_test_harness_tail.h"

mercurial