Modern IDB: storage/indexeddb/modern/index-3.html fails.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jan 2016 21:22:40 +0000 (21:22 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jan 2016 21:22:40 +0000 (21:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153661

Reviewed by Tim Horton.

Source/WebCore:

No new tests (1 failing test now passes, others get closer).

When indexing a new record fails due to uniqueness constraints, remove all traces of the record.

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):

LayoutTests:

* platform/mac-wk1/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195838 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/mac-wk1/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

index 4ffa277..69fd47c 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-29  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: storage/indexeddb/modern/index-3.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=153661
+
+        Reviewed by Tim Horton.
+
+        * platform/mac-wk1/TestExpectations:
+
 2015-12-22  Pranjal Jumde  <pjumde@apple.com>
 
         Test to check for stack recursion when indexed propertyNames defined using Object.defineProperty are deleted.
index 125c96a..66ad4d1 100644 (file)
@@ -259,7 +259,6 @@ storage/indexeddb/cursor-continue-validity.html [ Failure ]
 storage/indexeddb/cursor-primary-key-order.html [ Failure ]
 storage/indexeddb/get-keyrange.html [ Failure ]
 storage/indexeddb/modern/get-keyrange.html [ Failure ]
-storage/indexeddb/modern/index-3.html [ Failure ]
 
 # SQLite backend tests that timeout
 storage/indexeddb/modern/transaction-scheduler-1.html [ Skip ]
index f9c567a..e51be2c 100644 (file)
@@ -1,3 +1,19 @@
+2016-01-29  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: storage/indexeddb/modern/index-3.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=153661
+
+        Reviewed by Tim Horton.
+
+        No new tests (1 failing test now passes, others get closer).
+
+        When indexing a new record fails due to uniqueness constraints, remove all traces of the record.
+
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
+
 2016-01-29  Brent Fulgham  <bfulgham@apple.com>
 
         [WebGL] Check vertex array bounds before permitting a glDrawArrays to execute
index 0e1305d..70a71ee 100644 (file)
@@ -763,7 +763,15 @@ IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transac
 
         IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
         if (!error.isNull()) {
-            // FIXME: Remove this newly added index.
+            SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
+            if (sql.prepare() != SQLITE_OK
+                || sql.bindInt64(1, info.identifier()) != SQLITE_OK
+                || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
+                || sql.step() != SQLITE_DONE) {
+                LOG_ERROR("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database");
+                return { IDBDatabaseException::UnknownError, ASCIILiteral("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database") };
+            }
+
             return error;
         }
 
@@ -1090,8 +1098,7 @@ IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStor
         return { };
 
     IDBError error;
-    Vector<std::pair<uint64_t, IndexKey>> changedIndexRecords;
-
+    bool anyRecordsSucceeded = false;
     for (auto& index : info.indexMap().values()) {
         IndexKey indexKey;
         generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
@@ -1103,10 +1110,22 @@ IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStor
         if (!error.isNull())
             break;
 
-        changedIndexRecords.append(std::make_pair(index.identifier(), indexKey));
+        anyRecordsSucceeded = true;
     }
 
-    // FIXME: If any of the index puts failed, revert the ones that went through (changedIndexRecords).
+    if (!error.isNull() && anyRecordsSucceeded) {
+        RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(key);
+
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
+
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindInt64(1, info.identifier()) != SQLITE_OK
+            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR("Adding one Index record failed, but failed to remove all others that previously succeeded");
+            return { IDBDatabaseException::UnknownError, ASCIILiteral("Adding one Index record failed, but failed to remove all others that previously succeeded") };
+        }
+    }
 
     return error;
 }
@@ -1148,7 +1167,16 @@ IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transacti
 
     auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value);
 
-    // FIXME: If there was an error indexing this record, remove it.
+    if (!error.isNull()) {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
+            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR("Indexing new object store record failed, but unable to remove the object store record itself");
+            return { IDBDatabaseException::UnknownError, ASCIILiteral("Indexing new object store record failed, but unable to remove the object store record itself") };
+        }
+    }
 
     transaction->notifyCursorsOfChanges(objectStoreInfo.identifier());