Bug 702809: Allow creating indexes with empty keyPaths. r=sicking

This commit is contained in:
Kyle Huey 2011-11-23 09:15:15 -05:00
parent c965e7cae0
commit 1d1f1cf7eb
3 changed files with 105 additions and 8 deletions

View File

@ -428,7 +428,9 @@ GetKeyFromValue(JSContext* aCx,
Key& aKey)
{
NS_ASSERTION(aCx, "Null pointer!");
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(aVal), "Why are we here!?");
// aVal can be primitive iff the key path is empty.
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(aVal) || aKeyPath.IsEmpty(),
"Why are we here!?");
NS_ASSERTION(IDBObjectStore::IsValidKeyPath(aCx, aKeyPath),
"This will explode!");
@ -580,7 +582,6 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
{
NS_ASSERTION(aData, "Null pointer!");
NS_ASSERTION(aDataLength, "Empty data!");
NS_ASSERTION(!aKeyPath.IsEmpty(), "Empty keyPath!");
NS_ASSERTION(aCx, "Null pointer!");
JSAutoRequest ar(aCx);
@ -592,7 +593,7 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
if (JSVAL_IS_PRIMITIVE(clone)) {
if (JSVAL_IS_PRIMITIVE(clone) && !aKeyPath.IsEmpty()) {
// This isn't an object, so just leave the key unset.
aValue.Unset();
return NS_OK;
@ -614,7 +615,7 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
JSObject* cloneObj = nsnull;
PRUint32 count = aObjectStoreInfo->indexes.Length();
if (count && !JSVAL_IS_PRIMITIVE(aObject)) {
if (count) {
if (!aUpdateInfoArray.SetCapacity(count)) {
NS_ERROR("Out of memory!");
return NS_ERROR_OUT_OF_MEMORY;
@ -623,6 +624,10 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
for (PRUint32 indexesIndex = 0; indexesIndex < count; indexesIndex++) {
const IndexInfo& indexInfo = aObjectStoreInfo->indexes[indexesIndex];
if (JSVAL_IS_PRIMITIVE(aObject) && !indexInfo.keyPath.IsEmpty()) {
continue;
}
Key value;
nsresult rv = GetKeyFromValue(aCx, aObject, indexInfo.keyPath, value);
NS_ENSURE_SUCCESS(rv, rv);
@ -1334,10 +1339,6 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
{
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
if (aKeyPath.IsEmpty()) {
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
}
if (!IsValidKeyPath(aCx, aKeyPath)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}

View File

@ -75,6 +75,7 @@ TEST_FILES = \
test_exceptions_in_success_events.html \
test_getAll.html \
test_global_data.html \
test_index_empty_keyPath.html \
test_index_getAll.html \
test_index_getAllObjects.html \
test_index_object_cursors.html \

View File

@ -0,0 +1,95 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
const objectStoreData = [
{ key: "1", value: "foo" },
{ key: "2", value: "bar" },
{ key: "3", value: "baz" }
];
let request = mozIndexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield; // upgradeneeded
let db = event.target.result;
let objectStore = db.createObjectStore("data", { keyPath: null });
// First, add all our data to the object store.
let addedData = 0;
for (let i in objectStoreData) {
request = objectStore.add(objectStoreData[i].value,
objectStoreData[i].key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
if (++addedData == objectStoreData.length) {
testGenerator.send(event);
}
}
}
event = yield; // testGenerator.send
// Now create the index.
objectStore.createIndex("set", "", { unique: true });
yield; // success
let trans = db.transaction("data", IDBTransaction.READ_WRITE);
objectStore = trans.objectStore("data");
index = objectStore.index("set");
let request = index.get("bar");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
is(event.target.result, "bar", "Got correct result");
let request = objectStore.add("foopy", 4);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
yield;
let request = index.get("foopy");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
is(event.target.result, "foopy", "Got correct result");
let request = objectStore.add("foopy", 5);
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
request.onsuccess = unexpectedSuccessHandler;
trans.oncomplete = grabEventAndContinueHandler;
yield;
yield;
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>