Better cached statements

This commit is contained in:
Ben Turner 2010-06-05 15:16:00 -07:00
parent 82f1c80364
commit 0400b752ac
5 changed files with 243 additions and 373 deletions

View File

@ -46,6 +46,7 @@
#include "nsIIDBDatabaseException.h"
#include "nsIVariant.h"
#include "mozilla/Storage.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"

View File

@ -529,11 +529,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
return nsIIDBDatabaseException::UNKNOWN_ERR;
}
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(query, getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindInt64ByName(indexId, mId);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(indexId, mId);
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
PRBool hasResult;

View File

@ -1358,13 +1358,15 @@ AddHelper::UpdateIndexes(mozIStorageConnection* aConnection,
nsresult rv;
if (!mAutoIncrement) {
rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id "
"FROM object_data "
"WHERE object_store_id = :osid "
"AND key_value = :key_value"
), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);
stmt = mTransaction->GetCachedStatement(
"SELECT id "
"FROM object_data "
"WHERE object_store_id = :osid "
"AND key_value = :key_value"
);
NS_ENSURE_TRUE(stmt, NS_ERROR_FAILURE);
mozStorageStatementScoper scoper(stmt);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mOSID);
NS_ENSURE_SUCCESS(rv, rv);
@ -1459,6 +1461,7 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->GetStatement(mAutoIncrement);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mOSID);
@ -1514,6 +1517,7 @@ RemoveHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->RemoveStatement(mAutoIncrement);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mOSID);
@ -1626,11 +1630,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
return nsIIDBDatabaseException::UNKNOWN_ERR;
}
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(query, getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
if (!mLeftKey.IsUnset()) {
@ -1733,15 +1738,17 @@ CreateIndexHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
Savepoint savepoint(mTransaction);
// Insert the data into the database.
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->GetCachedStatement(
"INSERT INTO object_store_index (name, key_path, unique_index, "
"object_store_id, object_store_autoincrement) "
"VALUES (:name, :key_path, :unique, :osid, :os_auto_increment)"
), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mName);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mName);
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"), mKeyPath);
@ -1793,11 +1800,14 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
sql.AppendASCII(" FROM ");
sql += table;
sql.AppendASCII(" WHERE object_store_id = :osid");
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(sql, getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mObjectStore->Id());
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(sql);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"),
mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
PRBool hasResult;
@ -1805,7 +1815,8 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
nsCOMPtr<mozIStorageStatement> insertStmt =
mTransaction->IndexUpdateStatement(mAutoIncrement, mUnique);
NS_ENSURE_TRUE(insertStmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(insertStmt);
mozStorageStatementScoper scoper2(insertStmt);
rv = insertStmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"), mId);
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
@ -1910,14 +1921,16 @@ RemoveIndexHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM object_store_index "
"WHERE name = :name "
), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->GetCachedStatement(
"DELETE FROM object_store_index "
"WHERE name = :name "
);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mName);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mName);
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
if (NS_FAILED(stmt->Execute())) {

View File

@ -39,6 +39,7 @@
#include "IDBTransactionRequest.h"
#include "mozilla/Storage.h"
#include "nsDOMClassInfo.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
@ -55,6 +56,21 @@
USING_INDEXEDDB_NAMESPACE
namespace {
PLDHashOperator
DoomCachedStatements(const nsACString& aQuery,
nsCOMPtr<mozIStorageStatement>& aStatement,
void* aUserArg)
{
CloseConnectionRunnable* runnable =
static_cast<CloseConnectionRunnable*>(aUserArg);
runnable->AddDoomedObject(aStatement);
return PL_DHASH_REMOVE;
}
} // anonymous namespace
BEGIN_INDEXEDDB_NAMESPACE
class CommitHelper : public nsRunnable
@ -92,6 +108,11 @@ IDBTransactionRequest::Create(IDBDatabaseRequest* aDatabase,
return nsnull;
}
if (!transaction->mCachedStatements.Init()) {
NS_ERROR("Failed to initialize hash!");
return nsnull;
}
return transaction.forget();
}
@ -249,359 +270,218 @@ IDBTransactionRequest::AddStatement(bool aCreate,
bool aAutoIncrement)
{
#ifdef DEBUG
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
if (!aCreate) {
NS_ASSERTION(aOverwrite, "Bad param combo!");
}
#endif
NS_ASSERTION(mConnection, "No connection!");
nsCOMPtr<mozIStorageStatement>& cachedStatement =
aAutoIncrement ?
aCreate ?
aOverwrite ?
mAddOrModifyAutoIncrementStmt :
mAddAutoIncrementStmt :
mModifyAutoIncrementStmt :
aCreate ?
aOverwrite ?
mAddOrModifyStmt :
mAddStmt :
mModifyStmt;
nsCOMPtr<mozIStorageStatement> result(cachedStatement);
if (!result) {
nsCString query;
if (aAutoIncrement) {
if (aCreate) {
if (aOverwrite) {
query.AssignLiteral(
"INSERT OR REPLACE INTO ai_object_data (object_store_id, id, data) "
"VALUES (:osid, :key_value, :data)"
);
}
else {
query.AssignLiteral(
"INSERT INTO ai_object_data (object_store_id, data) "
"VALUES (:osid, :data)"
);
}
}
else {
query.AssignLiteral(
"UPDATE ai_object_data "
"SET data = :data "
"WHERE object_store_id = :osid "
"AND id = :key_value"
if (aAutoIncrement) {
if (aCreate) {
if (aOverwrite) {
return GetCachedStatement(
"INSERT OR REPLACE INTO ai_object_data (object_store_id, id, data) "
"VALUES (:osid, :key_value, :data)"
);
}
return GetCachedStatement(
"INSERT INTO ai_object_data (object_store_id, data) "
"VALUES (:osid, :data)"
);
}
else {
if (aCreate) {
if (aOverwrite) {
query.AssignLiteral(
"INSERT OR REPLACE INTO object_data (object_store_id, key_value, "
"data) "
"VALUES (:osid, :key_value, :data)"
);
}
else {
query.AssignLiteral(
"INSERT INTO object_data (object_store_id, key_value, data) "
"VALUES (:osid, :key_value, :data)"
);
}
}
else {
query.AssignLiteral(
"UPDATE object_data "
"SET data = :data "
"WHERE object_store_id = :osid "
"AND key_value = :key_value"
);
}
}
nsresult rv = mConnection->CreateStatement(query,
getter_AddRefs(cachedStatement));
NS_ENSURE_SUCCESS(rv, nsnull);
result = cachedStatement;
return GetCachedStatement(
"UPDATE ai_object_data "
"SET data = :data "
"WHERE object_store_id = :osid "
"AND id = :key_value"
);
}
return result.forget();
if (aCreate) {
if (aOverwrite) {
return GetCachedStatement(
"INSERT OR REPLACE INTO object_data (object_store_id, key_value, data) "
"VALUES (:osid, :key_value, :data)"
);
}
return GetCachedStatement(
"INSERT INTO object_data (object_store_id, key_value, data) "
"VALUES (:osid, :key_value, :data)"
);
}
return GetCachedStatement(
"UPDATE object_data "
"SET data = :data "
"WHERE object_store_id = :osid "
"AND key_value = :key_value"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::RemoveStatement(bool aAutoIncrement)
{
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mConnection, "No connection!");
nsCOMPtr<mozIStorageStatement> result;
nsresult rv;
if (aAutoIncrement) {
if (!mRemoveAutoIncrementStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM ai_object_data "
"WHERE id = :key_value "
"AND object_store_id = :osid"
), getter_AddRefs(mRemoveAutoIncrementStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mRemoveAutoIncrementStmt;
return GetCachedStatement(
"DELETE FROM ai_object_data "
"WHERE id = :key_value "
"AND object_store_id = :osid"
);
}
else {
if (!mRemoveStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM object_data "
"WHERE key_value = :key_value "
"AND object_store_id = :osid"
), getter_AddRefs(mRemoveStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mRemoveStmt;
}
return result.forget();
return GetCachedStatement(
"DELETE FROM object_data "
"WHERE key_value = :key_value "
"AND object_store_id = :osid"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::GetStatement(bool aAutoIncrement)
{
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mConnection, "No connection!");
nsCOMPtr<mozIStorageStatement> result;
nsresult rv;
if (aAutoIncrement) {
if (!mGetAutoIncrementStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM ai_object_data "
"WHERE id = :id "
"AND object_store_id = :osid"
), getter_AddRefs(mGetAutoIncrementStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mGetAutoIncrementStmt;
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"WHERE id = :id "
"AND object_store_id = :osid"
);
}
else {
if (!mGetStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM object_data "
"WHERE key_value = :id "
"AND object_store_id = :osid"
), getter_AddRefs(mGetStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mGetStmt;
}
return result.forget();
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"WHERE key_value = :id "
"AND object_store_id = :osid"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::IndexGetStatement(bool aUnique,
bool aAutoIncrement)
{
nsCOMPtr<mozIStorageStatement> result;
nsresult rv;
if (aAutoIncrement) {
if (aUnique) {
if (!mIndexGetUniqueAIStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT ai_object_data_id "
"FROM unique_ai_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetUniqueAIStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetUniqueAIStmt;
}
else {
if (!mIndexGetAIStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT ai_object_data_id "
"FROM ai_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetAIStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetAIStmt;
return GetCachedStatement(
"SELECT ai_object_data_id "
"FROM unique_ai_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT ai_object_data_id "
"FROM ai_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
else {
if (aUnique) {
if (!mIndexGetUniqueStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT object_data_key "
"FROM unique_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetUniqueStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetUniqueStmt;
}
else {
if (!mIndexGetStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT object_data_key "
"FROM index_data "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetStmt;
}
if (aUnique) {
return GetCachedStatement(
"SELECT object_data_key "
"FROM unique_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return result.forget();
return GetCachedStatement(
"SELECT object_data_key "
"FROM index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::IndexGetObjectStatement(bool aUnique,
bool aAutoIncrement)
{
nsCOMPtr<mozIStorageStatement> result;
nsresult rv;
if (aAutoIncrement) {
if (aUnique) {
if (!mIndexGetObjectUniqueAIStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN unique_ai_index_data "
"ON object_data.id = unique_ai_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetObjectUniqueAIStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetObjectUniqueAIStmt;
}
else {
if (!mIndexGetObjectAIStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN ai_index_data "
"ON object_data.id = ai_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetObjectAIStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetObjectAIStmt;
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN unique_ai_index_data "
"ON object_data.id = unique_ai_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN ai_index_data "
"ON object_data.id = ai_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
else {
if (aUnique) {
if (!mIndexGetObjectUniqueStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM object_data "
"INNER JOIN unique_index_data "
"ON object_data.id = unique_index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetObjectUniqueStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetObjectUniqueStmt;
}
else {
if (!mIndexGetObjectStmt) {
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
"SELECT data "
"FROM object_data "
"INNER JOIN index_data "
"ON object_data.id = index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
), getter_AddRefs(mIndexGetObjectStmt));
NS_ENSURE_SUCCESS(rv, nsnull);
}
result = mIndexGetObjectStmt;
}
if (aUnique) {
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"INNER JOIN unique_index_data "
"ON object_data.id = unique_index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return result.forget();
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"INNER JOIN index_data "
"ON object_data.id = index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::IndexUpdateStatement(bool aAutoIncrement,
bool aUnique)
{
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
if (aAutoIncrement) {
if (aUnique) {
return GetCachedStatement(
"INSERT OR REPLACE INTO ai_unique_index_data "
"(index_id, object_data_id, id, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
return GetCachedStatement(
"INSERT OR REPLACE INTO ai_index_data "
"(index_id, object_data_id, id, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
if (aUnique) {
return GetCachedStatement(
"INSERT OR REPLACE INTO unique_index_data "
"(index_id, object_data_id, object_data_key, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
return GetCachedStatement(
"INSERT OR REPLACE INTO index_data ("
"index_id, object_data_id, object_data_key, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransactionRequest::GetCachedStatement(const nsACString& aQuery)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!aQuery.IsEmpty(), "Empty sql statement!");
NS_ASSERTION(mConnection, "No connection!");
nsCOMPtr<mozIStorageStatement>& cachedStatement =
aAutoIncrement ?
aUnique ?
mIndexUpdateUniqueAIStmt :
mIndexUpdateAIStmt :
aUnique ?
mIndexUpdateUniqueStmt :
mIndexUpdateStmt;
nsCOMPtr<mozIStorageStatement> stmt;
nsCOMPtr<mozIStorageStatement> result(cachedStatement);
if (!result) {
nsCString query;
if (aAutoIncrement) {
if (aUnique) {
query.AssignLiteral(
"INSERT OR REPLACE INTO ai_unique_index_data (index_id, "
"object_data_id, "
"id, "
"value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
else {
query.AssignLiteral(
"INSERT OR REPLACE INTO ai_index_data (index_id, object_data_id, "
"id, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
}
else {
if (aUnique) {
query.AssignLiteral(
"INSERT OR REPLACE INTO unique_index_data (index_id, object_data_id, "
"object_data_key, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
else {
query.AssignLiteral(
"INSERT OR REPLACE INTO index_data (index_id, object_data_id, "
"object_data_key, value) "
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
);
}
}
nsresult rv = mConnection->CreateStatement(query,
getter_AddRefs(cachedStatement));
if (!mCachedStatements.Get(aQuery, getter_AddRefs(stmt))) {
nsresult rv = mConnection->CreateStatement(aQuery, getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, nsnull);
result = cachedStatement;
if (!mCachedStatements.Put(aQuery, stmt)) {
NS_ERROR("Out of memory?!");
}
}
return result.forget();
return stmt.forget();
}
void
@ -615,29 +495,10 @@ IDBTransactionRequest::CloseConnection()
nsRefPtr<CloseConnectionRunnable> runnable(new CloseConnectionRunnable());
if (!runnable->AddDoomedObject(mConnection) ||
!runnable->AddDoomedObject(mAddStmt) ||
!runnable->AddDoomedObject(mAddAutoIncrementStmt) ||
!runnable->AddDoomedObject(mModifyStmt) ||
!runnable->AddDoomedObject(mModifyAutoIncrementStmt) ||
!runnable->AddDoomedObject(mAddOrModifyStmt) ||
!runnable->AddDoomedObject(mAddOrModifyAutoIncrementStmt) ||
!runnable->AddDoomedObject(mRemoveStmt) ||
!runnable->AddDoomedObject(mRemoveAutoIncrementStmt) ||
!runnable->AddDoomedObject(mGetStmt) ||
!runnable->AddDoomedObject(mGetAutoIncrementStmt) ||
!runnable->AddDoomedObject(mIndexGetUniqueAIStmt) ||
!runnable->AddDoomedObject(mIndexGetAIStmt) ||
!runnable->AddDoomedObject(mIndexGetUniqueStmt) ||
!runnable->AddDoomedObject(mIndexGetStmt) ||
!runnable->AddDoomedObject(mIndexGetObjectUniqueAIStmt) ||
!runnable->AddDoomedObject(mIndexGetObjectAIStmt) ||
!runnable->AddDoomedObject(mIndexGetObjectUniqueStmt) ||
!runnable->AddDoomedObject(mIndexGetObjectStmt) ||
!runnable->AddDoomedObject(mIndexUpdateUniqueAIStmt) ||
!runnable->AddDoomedObject(mIndexUpdateAIStmt) ||
!runnable->AddDoomedObject(mIndexUpdateUniqueStmt) ||
!runnable->AddDoomedObject(mIndexUpdateStmt)) {
mCachedStatements.Enumerate(DoomCachedStatements, runnable);
NS_ASSERTION(!mCachedStatements.Count(), "Statements left!");
if (!runnable->AddDoomedObject(mConnection)) {
NS_ERROR("Out of memory!");
}

View File

@ -50,7 +50,8 @@
#include "nsCycleCollectionParticipant.h"
#include "nsAutoPtr.h"
#include "mozilla/Storage.h"
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"
class nsIThread;
@ -113,6 +114,18 @@ public:
IndexUpdateStatement(bool aAutoIncrement,
bool aUnique);
already_AddRefed<mozIStorageStatement>
GetCachedStatement(const nsACString& aQuery);
template<int N>
already_AddRefed<mozIStorageStatement>
GetCachedStatement(const char (&aQuery)[N])
{
nsCString query;
query.AssignLiteral(aQuery);
return GetCachedStatement(query);
}
#ifdef DEBUG
bool TransactionIsOpen() const;
bool IsWriteAllowed() const;
@ -152,30 +165,11 @@ private:
nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnTimeoutListener;
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
mCachedStatements;
// Only touched on the database thread.
nsCOMPtr<mozIStorageConnection> mConnection;
nsCOMPtr<mozIStorageStatement> mAddStmt;
nsCOMPtr<mozIStorageStatement> mAddAutoIncrementStmt;
nsCOMPtr<mozIStorageStatement> mModifyStmt;
nsCOMPtr<mozIStorageStatement> mModifyAutoIncrementStmt;
nsCOMPtr<mozIStorageStatement> mAddOrModifyStmt;
nsCOMPtr<mozIStorageStatement> mAddOrModifyAutoIncrementStmt;
nsCOMPtr<mozIStorageStatement> mRemoveStmt;
nsCOMPtr<mozIStorageStatement> mRemoveAutoIncrementStmt;
nsCOMPtr<mozIStorageStatement> mGetStmt;
nsCOMPtr<mozIStorageStatement> mGetAutoIncrementStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetUniqueAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetUniqueStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetObjectUniqueAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetObjectAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetObjectUniqueStmt;
nsCOMPtr<mozIStorageStatement> mIndexGetObjectStmt;
nsCOMPtr<mozIStorageStatement> mIndexUpdateUniqueAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexUpdateAIStmt;
nsCOMPtr<mozIStorageStatement> mIndexUpdateUniqueStmt;
nsCOMPtr<mozIStorageStatement> mIndexUpdateStmt;
// Only touched on the database thread.
PRUint32 mSavepointCount;