Title: [104755] trunk
Revision
104755
Author
[email protected]
Date
2012-01-11 15:51:15 -0800 (Wed, 11 Jan 2012)

Log Message

IndexedDB: Version change transaction should abort if constraints fail during createIndex
https://bugs.webkit.org/show_bug.cgi?id=76094

Patch by Joshua Bell <[email protected]> on 2012-01-11
Reviewed by Tony Chang.

Source/WebCore:

Test: storage/indexeddb/index-population.html

* storage/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::addingKeyAllowed):
* storage/IDBIndexBackendImpl.h:
* storage/IDBLevelDBBackingStore.cpp:
(WebCore::IDBLevelDBBackingStore::forEachObjectStoreRecord):
* storage/IDBObjectStoreBackendImpl.cpp:

LayoutTests:

* storage/indexeddb/index-population-expected.txt: Added.
* storage/indexeddb/index-population.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (104754 => 104755)


--- trunk/LayoutTests/ChangeLog	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/LayoutTests/ChangeLog	2012-01-11 23:51:15 UTC (rev 104755)
@@ -1,3 +1,13 @@
+2012-01-11  Joshua Bell  <[email protected]>
+
+        IndexedDB: Version change transaction should abort if constraints fail during createIndex
+        https://bugs.webkit.org/show_bug.cgi?id=76094
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/index-population-expected.txt: Added.
+        * storage/indexeddb/index-population.html: Added.
+
 2012-01-11  Mike Lawther  <[email protected]>
 
         line height test for CSS3 calc

Added: trunk/LayoutTests/storage/indexeddb/index-population-expected.txt (0 => 104755)


--- trunk/LayoutTests/storage/indexeddb/index-population-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/index-population-expected.txt	2012-01-11 23:51:15 UTC (rev 104755)
@@ -0,0 +1,52 @@
+Test IndexedDB index population.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = window.indexedDB || window.webkitIndexedDB
+PASS indexedDB != null is true
+IDBIndex = window.IDBIndex || window.webkitIDBIndex
+PASS IDBIndex != null is true
+IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange
+PASS IDBKeyRange != null is true
+indexedDB.deleteDatabase('index-population')
+indexedDB.open('index-population')
+
+doSetVersion1():
+db = event.target.result
+request = db.setVersion('version 1')
+
+setVersion1():
+transaction = request.result
+store = db.createObjectStore('store1')
+store.put({data: 'a', indexKey: 10}, 1)
+store.put({data: 'b', indexKey: 20}, 2)
+store.put({data: 'c', indexKey: 10}, 3)
+store.put({data: 'd', indexKey: 20}, 4)
+index = store.createIndex('index1', 'indexKey')
+PASS index instanceof IDBIndex is true
+PASS index.unique is false
+request = index.count(IDBKeyRange.bound(-Infinity, Infinity))
+PASS request.result is 4
+
+doSetVersion2():
+request = db.setVersion('version 2')
+
+setVersion2():
+transaction = request.result
+store = db.createObjectStore('store2')
+store.put({data: 'a', indexKey: 10}, 1)
+store.put({data: 'b', indexKey: 20}, 2)
+store.put({data: 'c', indexKey: 10}, 3)
+store.put({data: 'd', indexKey: 20}, 4)
+index2 = store.createIndex('index2', 'indexKey', { unique: true })
+PASS index2 instanceof IDBIndex is true
+PASS index2.unique is true
+
+setVersion2Abort():
+PASS db.objectStoreNames.length is 1
+PASS db.objectStoreNames[0] is 'store1'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/indexeddb/index-population.html (0 => 104755)


--- trunk/LayoutTests/storage/indexeddb/index-population.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/index-population.html	2012-01-11 23:51:15 UTC (rev 104755)
@@ -0,0 +1,107 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("Test IndexedDB index population.");
+
+function test()
+{
+    evalAndLog("indexedDB = window.indexedDB || window.webkitIndexedDB");
+    shouldBeTrue("indexedDB != null");
+    evalAndLog("IDBIndex = window.IDBIndex || window.webkitIDBIndex");
+    shouldBeTrue("IDBIndex != null");
+    evalAndLog("IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange");
+    shouldBeTrue("IDBKeyRange != null");
+
+    request = evalAndLog("indexedDB.deleteDatabase('index-population')");
+    request._onsuccess_ = deleteSuccess;
+    request._onerror_ = unexpectedErrorCallback;
+}
+
+function deleteSuccess()
+{
+    request = evalAndLog("indexedDB.open('index-population')");
+    request._onsuccess_ = doSetVersion1;
+    request._onerror_ = unexpectedErrorCallback;
+}
+
+function doSetVersion1()
+{
+    debug("");
+    debug("doSetVersion1():");
+    window.db = evalAndLog("db = event.target.result");
+    request = evalAndLog("request = db.setVersion('version 1')");
+    request._onsuccess_ = setVersion1;
+    request._onerror_ = unexpectedErrorCallback;
+}
+
+function setVersion1()
+{
+    debug("");
+    debug("setVersion1():");
+    transaction = evalAndLog("transaction = request.result");
+    transaction._onerror_ = unexpectedErrorCallback;
+    transaction._onabort_ = unexpectedAbortCallback;
+    store = evalAndLog("store = db.createObjectStore('store1')");
+    evalAndLog("store.put({data: 'a', indexKey: 10}, 1)");
+    evalAndLog("store.put({data: 'b', indexKey: 20}, 2)");
+    evalAndLog("store.put({data: 'c', indexKey: 10}, 3)");
+    evalAndLog("store.put({data: 'd', indexKey: 20}, 4)");
+    evalAndLog("index = store.createIndex('index1', 'indexKey')");
+    shouldBeTrue("index instanceof IDBIndex");
+    shouldBeFalse("index.unique");
+    request = evalAndLog("request = index.count(IDBKeyRange.bound(-Infinity, Infinity))");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function () {
+        shouldBe("request.result", "4");
+    };
+    transaction._oncomplete_ = doSetVersion2;
+}
+
+function doSetVersion2() {
+    debug("");
+    debug("doSetVersion2():");
+    request = evalAndLog("request = db.setVersion('version 2')");
+    request._onsuccess_ = setVersion2;
+    request._onerror_ = unexpectedErrorCallback;
+}
+
+function setVersion2()
+{
+    debug("");
+    debug("setVersion2():");
+    transaction2 = evalAndLog("transaction = request.result");
+    transaction2._onabort_ = setVersion2Abort;
+    transaction2._oncomplete_ = unexpectedCompleteCallback;
+    store = evalAndLog("store = db.createObjectStore('store2')");
+    evalAndLog("store.put({data: 'a', indexKey: 10}, 1)");
+    evalAndLog("store.put({data: 'b', indexKey: 20}, 2)");
+    evalAndLog("store.put({data: 'c', indexKey: 10}, 3)");
+    evalAndLog("store.put({data: 'd', indexKey: 20}, 4)");
+    evalAndLog("index2 = store.createIndex('index2', 'indexKey', { unique: true })");
+    shouldBeTrue("index2 instanceof IDBIndex");
+    shouldBeTrue("index2.unique");
+}
+
+function setVersion2Abort()
+{
+    debug("");
+    debug("setVersion2Abort():");
+    shouldBe("db.objectStoreNames.length", "1");
+    shouldBe("db.objectStoreNames[0]", "'store1'");
+    finishJSTest();
+}
+
+var jsTestIsAsync = true;
+test();
+
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (104754 => 104755)


--- trunk/Source/WebCore/ChangeLog	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/Source/WebCore/ChangeLog	2012-01-11 23:51:15 UTC (rev 104755)
@@ -1,3 +1,19 @@
+2012-01-11  Joshua Bell  <[email protected]>
+
+        IndexedDB: Version change transaction should abort if constraints fail during createIndex
+        https://bugs.webkit.org/show_bug.cgi?id=76094
+
+        Reviewed by Tony Chang.
+
+        Test: storage/indexeddb/index-population.html
+
+        * storage/IDBIndexBackendImpl.cpp:
+        (WebCore::IDBIndexBackendImpl::addingKeyAllowed):
+        * storage/IDBIndexBackendImpl.h:
+        * storage/IDBLevelDBBackingStore.cpp:
+        (WebCore::IDBLevelDBBackingStore::forEachObjectStoreRecord):
+        * storage/IDBObjectStoreBackendImpl.cpp:
+
 2012-01-11  Greg Billock  <[email protected]>
 
         Switch web intents to use supplemental IDL for DOMWindow

Modified: trunk/Source/WebCore/storage/IDBIndexBackendImpl.cpp (104754 => 104755)


--- trunk/Source/WebCore/storage/IDBIndexBackendImpl.cpp	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/Source/WebCore/storage/IDBIndexBackendImpl.cpp	2012-01-11 23:51:15 UTC (rev 104755)
@@ -192,7 +192,7 @@
     bool found = m_backingStore->keyExistsInIndex(m_databaseId, m_objectStoreBackend->id(), m_id, *indexKey, foundPrimaryKey);
     if (!found)
         return true;
-    if (foundPrimaryKey->isEqual(primaryKey))
+    if (primaryKey && foundPrimaryKey->isEqual(primaryKey))
         return true;
     return false;
 }

Modified: trunk/Source/WebCore/storage/IDBIndexBackendImpl.h (104754 => 104755)


--- trunk/Source/WebCore/storage/IDBIndexBackendImpl.h	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/Source/WebCore/storage/IDBIndexBackendImpl.h	2012-01-11 23:51:15 UTC (rev 104755)
@@ -58,7 +58,7 @@
     void setId(int64_t id) { m_id = id; }
     bool hasValidId() const { return m_id != InvalidId; };
 
-    bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey);
+    bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey = 0);
 
     // Implements IDBIndexBackendInterface.
     virtual String name() { return m_name; }

Modified: trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp (104754 => 104755)


--- trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2012-01-11 23:51:15 UTC (rev 104755)
@@ -659,7 +659,8 @@
         RefPtr<LevelDBRecordIdentifier> ri = LevelDBRecordIdentifier::create(encodeIDBKey(*primaryKey), version);
         String idbValue = decodeString(q, it->value().end());
 
-        callback.callback(ri.get(), idbValue);
+        if (!callback.callback(ri.get(), idbValue))
+            return false;
     }
 
     return true;

Modified: trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp (104754 => 104755)


--- trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp	2012-01-11 23:46:53 UTC (rev 104754)
+++ trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp	2012-01-11 23:51:15 UTC (rev 104755)
@@ -397,12 +397,16 @@
             return true;
 
         if (!m_index->multiEntry() || indexKey->type() != IDBKey::ArrayType) {
+            if (!m_index->addingKeyAllowed(indexKey.get()))
+                return false;
             if (!m_backingStore.putIndexDataForRecord(m_databaseId, m_objectStoreId, m_index->id(), *indexKey, recordIdentifier))
                 return false;
         } else {
             ASSERT(m_index->multiEntry());
             ASSERT(indexKey->type() == IDBKey::ArrayType);
             for (size_t i = 0; i < indexKey->array().size(); ++i) {
+                if (!m_index->addingKeyAllowed(indexKey.get()))
+                    return false;
                 if (!m_backingStore.putIndexDataForRecord(m_databaseId, m_objectStoreId, m_index->id(), *indexKey->array()[i], recordIdentifier))
                     return false;
             }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to