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

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 #include "storage_test_harness.h"
     6 #include "nsIEventTarget.h"
     7 #include "mozStorageConnection.h"
     9 #include "sqlite3.h"
    11 using namespace mozilla;
    12 using namespace mozilla::storage;
    14 ////////////////////////////////////////////////////////////////////////////////
    15 //// Helpers
    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 }
    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);
    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);
    59   // -- complete the execution
    60   asyncSpin->SpinUntilCompleted();
    62   // -- uninstall the transaction commit hook.
    63   static_cast<Connection *>(aDB)->setCommitHook(nullptr);
    65   // -- check transaction
    66   do_check_eq(aTransactionExpected, !!commit);
    68   // -- check that only one transaction was created.
    69   if (aTransactionExpected) {
    70     do_check_eq(1, commit);
    71   }
    73   // -- cleanup
    74   for (uint32_t i = 0; i < aStmtsLen; ++i) {
    75     aStmts[i]->Finalize();
    76   }
    77   blocking_async_close(aDB);
    78 }
    80 ////////////////////////////////////////////////////////////////////////////////
    81 //// Tests
    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());
    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));
    98   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
    99   db->CreateAsyncStatement(NS_LITERAL_CSTRING(
   100     "SELECT * FROM sqlite_master"
   101   ), getter_AddRefs(stmt2));
   103   mozIStorageBaseStatement *stmts[] = {
   104     stmt1,
   105     stmt2,
   106   };
   108   check_transaction(db, stmts, ArrayLength(stmts), false);
   109 }
   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());
   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));
   126   nsCOMPtr<mozIStorageStatement> stmt2;
   127   db->CreateStatement(NS_LITERAL_CSTRING(
   128     "SELECT * FROM sqlite_master"
   129   ), getter_AddRefs(stmt2));
   131   mozIStorageBaseStatement *stmts[] = {
   132     stmt1,
   133     stmt2,
   134   };
   136   check_transaction(db, stmts, ArrayLength(stmts), false);
   137 }
   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());
   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));
   154   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
   155   db->CreateAsyncStatement(NS_LITERAL_CSTRING(
   156     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
   157   ), getter_AddRefs(stmt2));
   159   mozIStorageBaseStatement *stmts[] = {
   160     stmt1,
   161     stmt2,
   162   };
   164   check_transaction(db, stmts, ArrayLength(stmts), true);
   165 }
   167 /**
   168  * Test that executing multiple Statements causing writes creates a transaction.
   169  */
   170 void
   171 test_MultipleReadWriteStatements()
   172 {
   173   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
   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));
   181   nsCOMPtr<mozIStorageStatement> stmt2;
   182   db->CreateStatement(NS_LITERAL_CSTRING(
   183     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
   184   ), getter_AddRefs(stmt2));
   186   mozIStorageBaseStatement *stmts[] = {
   187     stmt1,
   188     stmt2,
   189   };
   191   check_transaction(db, stmts, ArrayLength(stmts), true);
   192 }
   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());
   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));
   209   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
   210   db->CreateAsyncStatement(NS_LITERAL_CSTRING(
   211     "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
   212   ), getter_AddRefs(stmt2));
   214   mozIStorageBaseStatement *stmts[] = {
   215     stmt1,
   216     stmt2,
   217   };
   219   check_transaction(db, stmts, ArrayLength(stmts), true);
   220 }
   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());
   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));
   237   nsCOMPtr<mozIStorageStatement> stmt2;
   238   db->CreateStatement(NS_LITERAL_CSTRING(
   239     "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
   240   ), getter_AddRefs(stmt2));
   242   mozIStorageBaseStatement *stmts[] = {
   243     stmt1,
   244     stmt2,
   245   };
   247   check_transaction(db, stmts, ArrayLength(stmts), true);
   248 }
   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());
   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));
   265   mozIStorageBaseStatement *stmts[] = {
   266     stmt,
   267   };
   269   check_transaction(db, stmts, ArrayLength(stmts), false);
   270 }
   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());
   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));
   287   mozIStorageBaseStatement *stmts[] = {
   288     stmt,
   289   };
   291   check_transaction(db, stmts, ArrayLength(stmts), false);
   292 }
   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());
   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));
   309   mozIStorageBaseStatement *stmts[] = {
   310     stmt,
   311   };
   313   check_transaction(db, stmts, ArrayLength(stmts), true);
   314 }
   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());
   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));
   330   mozIStorageBaseStatement *stmts[] = {
   331     stmt,
   332   };
   334   check_transaction(db, stmts, ArrayLength(stmts), true);
   335 }
   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());
   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));
   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;
   364   mozIStorageBaseStatement *stmts[] = {
   365     stmt,
   366   };
   368   check_transaction(db, stmts, ArrayLength(stmts), false);
   369 }
   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());
   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));
   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;
   398   mozIStorageBaseStatement *stmts[] = {
   399     stmt,
   400   };
   402   check_transaction(db, stmts, ArrayLength(stmts), false);
   403 }
   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());
   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();
   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));
   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;
   440   mozIStorageBaseStatement *stmts[] = {
   441     stmt,
   442   };
   444   check_transaction(db, stmts, ArrayLength(stmts), true);
   445 }
   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());
   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();
   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));
   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;
   482   mozIStorageBaseStatement *stmts[] = {
   483     stmt,
   484   };
   486   check_transaction(db, stmts, ArrayLength(stmts), true);
   487 }
   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 };
   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