summaryrefslogtreecommitdiffstats
path: root/storage/test/test_asyncStatementExecution_transaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/test/test_asyncStatementExecution_transaction.cpp')
-rw-r--r--storage/test/test_asyncStatementExecution_transaction.cpp509
1 files changed, 509 insertions, 0 deletions
diff --git a/storage/test/test_asyncStatementExecution_transaction.cpp b/storage/test/test_asyncStatementExecution_transaction.cpp
new file mode 100644
index 000000000..7e94bd80e
--- /dev/null
+++ b/storage/test/test_asyncStatementExecution_transaction.cpp
@@ -0,0 +1,509 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#include "storage_test_harness.h"
+
+#include "nsIEventTarget.h"
+#include "mozStorageConnection.h"
+
+#include "sqlite3.h"
+
+using namespace mozilla;
+using namespace mozilla::storage;
+
+////////////////////////////////////////////////////////////////////////////////
+//// Helpers
+
+/**
+ * Commit hook to detect transactions.
+ *
+ * @param aArg
+ * An integer pointer that will be incremented for each commit.
+ */
+int commit_hook(void *aArg)
+{
+ int *arg = static_cast<int *>(aArg);
+ (*arg)++;
+ return 0;
+}
+
+/**
+ * Executes the passed-in statements and checks if a transaction is created.
+ * When done statements are finalized and database connection is closed.
+ *
+ * @param aDB
+ * The database connection.
+ * @param aStmts
+ * Vector of statements.
+ * @param aStmtsLen
+ * Number of statements.
+ * @param aTransactionExpected
+ * Whether a transaction is expected or not.
+ */
+void
+check_transaction(mozIStorageConnection *aDB,
+ mozIStorageBaseStatement **aStmts,
+ uint32_t aStmtsLen,
+ bool aTransactionExpected)
+{
+ // -- install a transaction commit hook.
+ int commit = 0;
+ static_cast<Connection *>(aDB)->setCommitHook(commit_hook, &commit);
+
+ RefPtr<AsyncStatementSpinner> asyncSpin(new AsyncStatementSpinner());
+ nsCOMPtr<mozIStoragePendingStatement> asyncPend;
+ do_check_success(aDB->ExecuteAsync(aStmts, aStmtsLen, asyncSpin,
+ getter_AddRefs(asyncPend)));
+ do_check_true(asyncPend);
+
+ // -- complete the execution
+ asyncSpin->SpinUntilCompleted();
+
+ // -- uninstall the transaction commit hook.
+ static_cast<Connection *>(aDB)->setCommitHook(nullptr);
+
+ // -- check transaction
+ do_check_eq(aTransactionExpected, !!commit);
+
+ // -- check that only one transaction was created.
+ if (aTransactionExpected) {
+ do_check_eq(1, commit);
+ }
+
+ // -- cleanup
+ for (uint32_t i = 0; i < aStmtsLen; ++i) {
+ aStmts[i]->Finalize();
+ }
+ blocking_async_close(aDB);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// Tests
+
+/**
+ * Test that executing multiple readonly AsyncStatements doesn't create a
+ * transaction.
+ */
+void
+test_MultipleAsyncReadStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing multiple readonly Statements doesn't create a
+ * transaction.
+ */
+void
+test_MultipleReadStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing multiple AsyncStatements causing writes creates a
+ * transaction.
+ */
+void
+test_MultipleAsyncReadWriteStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing multiple Statements causing writes creates a transaction.
+ */
+void
+test_MultipleReadWriteStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing multiple AsyncStatements causing writes creates a
+ * single transaction.
+ */
+void
+test_MultipleAsyncWriteStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test1 (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing multiple Statements causing writes creates a
+ * single transaction.
+ */
+void
+test_MultipleWriteStatements()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test1 (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test2 (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt2));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt1,
+ stmt2,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing a single read-only AsyncStatement doesn't create a
+ * transaction.
+ */
+void
+test_SingleAsyncReadStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing a single read-only Statement doesn't create a
+ * transaction.
+ */
+void
+test_SingleReadStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT * FROM sqlite_master"
+ ), getter_AddRefs(stmt));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing a single AsyncStatement causing writes creates a
+ * transaction.
+ */
+void
+test_SingleAsyncWriteStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing a single Statement causing writes creates a transaction.
+ */
+void
+test_SingleWriteStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(stmt));
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing a single read-only AsyncStatement with multiple params
+ * doesn't create a transaction.
+ */
+void
+test_MultipleParamsAsyncReadStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "SELECT :param FROM sqlite_master"
+ ), getter_AddRefs(stmt));
+
+ // -- bind multiple BindingParams
+ nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
+ stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
+ for (int32_t i = 0; i < 2; i++) {
+ nsCOMPtr<mozIStorageBindingParams> params;
+ paramsArray->NewBindingParams(getter_AddRefs(params));
+ params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing a single read-only Statement with multiple params
+ * doesn't create a transaction.
+ */
+void
+test_MultipleParamsReadStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "SELECT :param FROM sqlite_master"
+ ), getter_AddRefs(stmt));
+
+ // -- bind multiple BindingParams
+ nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
+ stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
+ for (int32_t i = 0; i < 2; i++) {
+ nsCOMPtr<mozIStorageBindingParams> params;
+ paramsArray->NewBindingParams(getter_AddRefs(params));
+ params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), false);
+}
+
+/**
+ * Test that executing a single write AsyncStatement with multiple params
+ * creates a transaction.
+ */
+void
+test_MultipleParamsAsyncWriteStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create a table for writes
+ nsCOMPtr<mozIStorageStatement> tableStmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(tableStmt));
+ tableStmt->Execute();
+ tableStmt->Finalize();
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement(NS_LITERAL_CSTRING(
+ "DELETE FROM test WHERE id = :param"
+ ), getter_AddRefs(stmt));
+
+ // -- bind multiple BindingParams
+ nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
+ stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
+ for (int32_t i = 0; i < 2; i++) {
+ nsCOMPtr<mozIStorageBindingParams> params;
+ paramsArray->NewBindingParams(getter_AddRefs(params));
+ params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+/**
+ * Test that executing a single write Statement with multiple params
+ * creates a transaction.
+ */
+void
+test_MultipleParamsWriteStatement()
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create a table for writes
+ nsCOMPtr<mozIStorageStatement> tableStmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "CREATE TABLE test (id INTEGER PRIMARY KEY)"
+ ), getter_AddRefs(tableStmt));
+ tableStmt->Execute();
+ tableStmt->Finalize();
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement(NS_LITERAL_CSTRING(
+ "DELETE FROM test WHERE id = :param"
+ ), getter_AddRefs(stmt));
+
+ // -- bind multiple BindingParams
+ nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
+ stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
+ for (int32_t i = 0; i < 2; i++) {
+ nsCOMPtr<mozIStorageBindingParams> params;
+ paramsArray->NewBindingParams(getter_AddRefs(params));
+ params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ mozIStorageBaseStatement *stmts[] = {
+ stmt,
+ };
+
+ check_transaction(db, stmts, ArrayLength(stmts), true);
+}
+
+void (*gTests[])(void) = {
+ test_MultipleAsyncReadStatements,
+ test_MultipleReadStatements,
+ test_MultipleAsyncReadWriteStatements,
+ test_MultipleReadWriteStatements,
+ test_MultipleAsyncWriteStatements,
+ test_MultipleWriteStatements,
+ test_SingleAsyncReadStatement,
+ test_SingleReadStatement,
+ test_SingleAsyncWriteStatement,
+ test_SingleWriteStatement,
+ test_MultipleParamsAsyncReadStatement,
+ test_MultipleParamsReadStatement,
+ test_MultipleParamsAsyncWriteStatement,
+ test_MultipleParamsWriteStatement,
+};
+
+const char *file = __FILE__;
+#define TEST_NAME "async statement execution transaction"
+#define TEST_FILE file
+#include "storage_test_harness_tail.h"