michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "storage_test_harness.h" michael@0: michael@0: #include "mozilla/storage/StatementCache.h" michael@0: using namespace mozilla::storage; michael@0: michael@0: /** michael@0: * This file test our statement cache in StatementCache.h. michael@0: */ michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// Helpers michael@0: michael@0: class SyncCache : public StatementCache michael@0: { michael@0: public: michael@0: SyncCache(nsCOMPtr& aConnection) michael@0: : StatementCache(aConnection) michael@0: { michael@0: } michael@0: }; michael@0: michael@0: class AsyncCache : public StatementCache michael@0: { michael@0: public: michael@0: AsyncCache(nsCOMPtr& aConnection) michael@0: : StatementCache(aConnection) michael@0: { michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * Wraps nsCString so we can not implement the same functions twice for each michael@0: * type. michael@0: */ michael@0: class StringWrapper : public nsCString michael@0: { michael@0: public: michael@0: StringWrapper(const char* aOther) michael@0: { michael@0: this->Assign(aOther); michael@0: } michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// Test Functions michael@0: michael@0: template michael@0: void michael@0: test_GetCachedStatement() michael@0: { michael@0: nsCOMPtr db(getMemoryDatabase()); michael@0: SyncCache cache(db); michael@0: michael@0: StringType sql = "SELECT * FROM sqlite_master"; michael@0: michael@0: // Make sure we get a statement back with the right state. michael@0: nsCOMPtr stmt = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt); michael@0: int32_t state; michael@0: do_check_success(stmt->GetState(&state)); michael@0: do_check_eq(mozIStorageBaseStatement::MOZ_STORAGE_STATEMENT_READY, state); michael@0: michael@0: // Check to make sure we get the same copy the second time we ask. michael@0: nsCOMPtr stmt2 = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt2); michael@0: do_check_eq(stmt.get(), stmt2.get()); michael@0: } michael@0: michael@0: template michael@0: void michael@0: test_FinalizeStatements() michael@0: { michael@0: nsCOMPtr db(getMemoryDatabase()); michael@0: SyncCache cache(db); michael@0: michael@0: StringType sql = "SELECT * FROM sqlite_master"; michael@0: michael@0: // Get a statement, and then tell the cache to finalize. michael@0: nsCOMPtr stmt = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt); michael@0: michael@0: cache.FinalizeStatements(); michael@0: michael@0: // We should be in an invalid state at this point. michael@0: int32_t state; michael@0: do_check_success(stmt->GetState(&state)); michael@0: do_check_eq(mozIStorageBaseStatement::MOZ_STORAGE_STATEMENT_INVALID, state); michael@0: michael@0: // Should be able to close the database now too. michael@0: do_check_success(db->Close()); michael@0: } michael@0: michael@0: template michael@0: void michael@0: test_GetCachedAsyncStatement() michael@0: { michael@0: nsCOMPtr db(getMemoryDatabase()); michael@0: AsyncCache cache(db); michael@0: michael@0: StringType sql = "SELECT * FROM sqlite_master"; michael@0: michael@0: // Make sure we get a statement back with the right state. michael@0: nsCOMPtr stmt = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt); michael@0: int32_t state; michael@0: do_check_success(stmt->GetState(&state)); michael@0: do_check_eq(mozIStorageBaseStatement::MOZ_STORAGE_STATEMENT_READY, state); michael@0: michael@0: // Check to make sure we get the same copy the second time we ask. michael@0: nsCOMPtr stmt2 = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt2); michael@0: do_check_eq(stmt.get(), stmt2.get()); michael@0: } michael@0: michael@0: template michael@0: void michael@0: test_FinalizeAsyncStatements() michael@0: { michael@0: nsCOMPtr db(getMemoryDatabase()); michael@0: AsyncCache cache(db); michael@0: michael@0: StringType sql = "SELECT * FROM sqlite_master"; michael@0: michael@0: // Get a statement, and then tell the cache to finalize. michael@0: nsCOMPtr stmt = cache.GetCachedStatement(sql); michael@0: do_check_true(stmt); michael@0: michael@0: cache.FinalizeStatements(); michael@0: michael@0: // We should be in an invalid state at this point. michael@0: int32_t state; michael@0: do_check_success(stmt->GetState(&state)); michael@0: do_check_eq(mozIStorageBaseStatement::MOZ_STORAGE_STATEMENT_INVALID, state); michael@0: michael@0: // Should be able to close the database now too. michael@0: do_check_success(db->AsyncClose(nullptr)); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// Test Harness Stuff michael@0: michael@0: void (*gTests[])(void) = { michael@0: test_GetCachedStatement, michael@0: test_GetCachedStatement, michael@0: test_FinalizeStatements, michael@0: test_FinalizeStatements, michael@0: test_GetCachedAsyncStatement, michael@0: test_GetCachedAsyncStatement, michael@0: test_FinalizeAsyncStatements, michael@0: test_FinalizeAsyncStatements, michael@0: }; michael@0: michael@0: const char *file = __FILE__; michael@0: #define TEST_NAME "StatementCache" michael@0: #define TEST_FILE file michael@0: #include "storage_test_harness_tail.h"