summaryrefslogtreecommitdiffstats
path: root/storage/test/gtest/test_asyncStatementExecution_transaction.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
commit9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /storage/test/gtest/test_asyncStatementExecution_transaction.cpp
parentInitial commit. (diff)
downloadthunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz
thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'storage/test/gtest/test_asyncStatementExecution_transaction.cpp')
-rw-r--r--storage/test/gtest/test_asyncStatementExecution_transaction.cpp445
1 files changed, 445 insertions, 0 deletions
diff --git a/storage/test/gtest/test_asyncStatementExecution_transaction.cpp b/storage/test/gtest/test_asyncStatementExecution_transaction.cpp
new file mode 100644
index 0000000000..0e7dec1e8a
--- /dev/null
+++ b/storage/test/gtest/test_asyncStatementExecution_transaction.cpp
@@ -0,0 +1,445 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#include "storage_test_harness.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,
+ const nsTArray<RefPtr<mozIStorageBaseStatement>>& aStmts,
+ 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, 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 < aStmts.Length(); ++i) {
+ aStmts[i]->Finalize();
+ }
+ blocking_async_close(aDB);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// Tests
+
+/**
+ * Test that executing multiple readonly AsyncStatements doesn't create a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleAsyncReadStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement("SELECT * FROM sqlite_master"_ns,
+ getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement("SELECT * FROM sqlite_master"_ns,
+ getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts.Clone(), false);
+}
+
+/**
+ * Test that executing multiple readonly Statements doesn't create a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleReadStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement("SELECT * FROM sqlite_master"_ns, getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement("SELECT * FROM sqlite_master"_ns, getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts, false);
+}
+
+/**
+ * Test that executing multiple AsyncStatements causing writes creates a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction,
+ MultipleAsyncReadWriteStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement("SELECT * FROM sqlite_master"_ns,
+ getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing multiple Statements causing writes creates a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleReadWriteStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement("SELECT * FROM sqlite_master"_ns, getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing multiple AsyncStatements causing writes creates a
+ * single transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleAsyncWriteStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt1;
+ db->CreateAsyncStatement("CREATE TABLE test1 (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageAsyncStatement> stmt2;
+ db->CreateAsyncStatement("CREATE TABLE test2 (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing multiple Statements causing writes creates a
+ * single transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleWriteStatements)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt1;
+ db->CreateStatement("CREATE TABLE test1 (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt1));
+
+ nsCOMPtr<mozIStorageStatement> stmt2;
+ db->CreateStatement("CREATE TABLE test2 (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt2));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt1)),
+ ToRefPtr(std::move(stmt2)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing a single read-only AsyncStatement doesn't create a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, SingleAsyncReadStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement("SELECT * FROM sqlite_master"_ns,
+ getter_AddRefs(stmt));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, false);
+}
+
+/**
+ * Test that executing a single read-only Statement doesn't create a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, SingleReadStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement("SELECT * FROM sqlite_master"_ns, getter_AddRefs(stmt));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, false);
+}
+
+/**
+ * Test that executing a single AsyncStatement causing writes creates a
+ * transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, SingleAsyncWriteStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing a single Statement causing writes creates a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, SingleWriteStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(stmt));
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing a single read-only AsyncStatement with multiple params
+ * doesn't create a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction,
+ MultipleParamsAsyncReadStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement("SELECT :param FROM sqlite_master"_ns,
+ 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("param"_ns, 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, false);
+}
+
+/**
+ * Test that executing a single read-only Statement with multiple params
+ * doesn't create a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleParamsReadStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement("SELECT :param FROM sqlite_master"_ns,
+ 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("param"_ns, 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, false);
+}
+
+/**
+ * Test that executing a single write AsyncStatement with multiple params
+ * creates a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction,
+ MultipleParamsAsyncWriteStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create a table for writes
+ nsCOMPtr<mozIStorageStatement> tableStmt;
+ db->CreateStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(tableStmt));
+ tableStmt->Execute();
+ tableStmt->Finalize();
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageAsyncStatement> stmt;
+ db->CreateAsyncStatement("DELETE FROM test WHERE id = :param"_ns,
+ 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("param"_ns, 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, true);
+}
+
+/**
+ * Test that executing a single write Statement with multiple params
+ * creates a transaction.
+ */
+TEST(storage_asyncStatementExecution_transaction, MultipleParamsWriteStatement)
+{
+ nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
+
+ // -- create a table for writes
+ nsCOMPtr<mozIStorageStatement> tableStmt;
+ db->CreateStatement("CREATE TABLE test (id INTEGER PRIMARY KEY)"_ns,
+ getter_AddRefs(tableStmt));
+ tableStmt->Execute();
+ tableStmt->Finalize();
+
+ // -- create statements and execute them
+ nsCOMPtr<mozIStorageStatement> stmt;
+ db->CreateStatement("DELETE FROM test WHERE id = :param"_ns,
+ 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("param"_ns, 1);
+ paramsArray->AddParams(params);
+ }
+ stmt->BindParameters(paramsArray);
+ paramsArray = nullptr;
+
+ nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+ ToRefPtr(std::move(stmt)),
+ };
+
+ check_transaction(db, stmts, true);
+}