diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 4e91d29f23f..667b5cddc3b 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -59,7 +59,7 @@ #include "IDBKeyRange.h" #include "LazyIdleThread.h" -#define DB_SCHEMA_VERSION 1 +#define DB_SCHEMA_VERSION 2 USING_INDEXEDDB_NAMESPACE @@ -155,7 +155,7 @@ CreateTables(mozIStorageConnection* aDBConn) NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX key_index " + "CREATE UNIQUE INDEX key_index " "ON object_data (key_value, object_store_id);" )); NS_ENSURE_SUCCESS(rv, rv); @@ -174,7 +174,7 @@ CreateTables(mozIStorageConnection* aDBConn) NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX ai_key_index " + "CREATE UNIQUE INDEX ai_key_index " "ON ai_object_data (id, object_store_id);" )); NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 8d50dc03c10..7ebb79aeaa8 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -1369,8 +1369,43 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection) rv = stmt->BindStringByName(NS_LITERAL_CSTRING("data"), mValue); NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR); - if (NS_FAILED(stmt->Execute())) { - return nsIIDBDatabaseException::CONSTRAINT_ERR; + rv = stmt->Execute(); + if (NS_FAILED(rv)) { + if (mCreate && mayOverwrite && rv == NS_ERROR_STORAGE_CONSTRAINT) { + scoper.Abandon(); + + stmt = mTransaction->AddStatement(false, true, mAutoIncrement); + NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR); + + mozStorageStatementScoper scoper2(stmt); + + rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mOSID); + NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR); + + if (!mAutoIncrement) { + NS_ASSERTION(!mKey.IsUnset(), "This shouldn't happen!"); + + if (mKey.IsInt()) { + rv = stmt->BindInt64ByName(keyValue, mKey.IntValue()); + } + else if (mKey.IsString()) { + rv = stmt->BindStringByName(keyValue, mKey.StringValue()); + } + else { + NS_NOTREACHED("Unknown key type!"); + } + NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR); + } + + rv = stmt->BindStringByName(NS_LITERAL_CSTRING("data"), mValue); + NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR); + + rv = stmt->Execute(); + } + + if (NS_FAILED(rv)) { + return nsIIDBDatabaseException::CONSTRAINT_ERR; + } } // If we are supposed to generate a key, get the new id. @@ -1777,10 +1812,9 @@ OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult) IDBCursor::Create(mRequest, mTransaction, mObjectStore, mDirection, mData); NS_ENSURE_TRUE(cursor, nsIIDBDatabaseException::UNKNOWN_ERR); - aResult->SetAsISupports(static_cast(cursor)); - mObjectStore = nsnull; + aResult->SetAsISupports(static_cast(cursor)); return OK; } @@ -1961,6 +1995,8 @@ CreateIndexHelper::GetSuccessResult(nsIWritableVariant* aResult) nsresult rv = mObjectStore->Index(mName, getter_AddRefs(result)); NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR); + mObjectStore = nsnull; + aResult->SetAsISupports(result); return OK; } @@ -2022,6 +2058,7 @@ RemoveIndexHelper::GetSuccessResult(nsIWritableVariant* /* aResult */) } } + mObjectStore = nsnull; return OK; } diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index 5b278408e1a..ac75299ac81 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -264,7 +264,7 @@ IDBTransaction::AddStatement(bool aCreate, if (aCreate) { if (aOverwrite) { return GetCachedStatement( - "INSERT OR REPLACE INTO ai_object_data (object_store_id, id, data) " + "INSERT OR FAIL INTO ai_object_data (object_store_id, id, data) " "VALUES (:osid, :key_value, :data)" ); } @@ -283,7 +283,7 @@ IDBTransaction::AddStatement(bool aCreate, if (aCreate) { if (aOverwrite) { return GetCachedStatement( - "INSERT OR REPLACE INTO object_data (object_store_id, key_value, data) " + "INSERT OR FAIL INTO object_data (object_store_id, key_value, data) " "VALUES (:osid, :key_value, :data)" ); }