tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_asyncStatementExecution_transaction.cpp (13530B)


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