storage/test/test_asyncStatementExecution_transaction.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial