Bug 694135: Don't throw if there are unknown properties in the options objects to createObjectStore/createIndex. r=bent
authorJonas Sicking <jonas@sicking.cc>
Mon, 07 Nov 2011 22:25:51 -0800
changeset 79930 e73f34291541f2bbd3b6d04a0f337ee6997e22d3
parent 79929 966c69671224f795dc099097c6d5402b70a81187
child 79931 c131defb532cefac282654ca5cb51d1850d0c2d4
push id21445
push usersicking@mozilla.com
push dateTue, 08 Nov 2011 06:29:57 +0000
treeherdermozilla-central@81dedcc49ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs694135
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 694135: Don't throw if there are unknown properties in the options objects to createObjectStore/createIndex. r=bent
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/test/test_add_twice_failure.html
dom/indexedDB/test/test_create_index.html
dom/indexedDB/test/test_create_objectStore.html
dom/indexedDB/test/test_cursor_update_updates_indexes.html
dom/indexedDB/test/test_indexes.html
dom/indexedDB/test/test_objectStore_remove_values.html
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -468,68 +468,55 @@ IDBDatabase::CreateObjectStore(const nsA
     return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
   }
 
   nsString keyPath;
   bool autoIncrement = false;
 
   if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) {
     if (JSVAL_IS_PRIMITIVE(aOptions)) {
-      // XXX Update spec for a real code here
-      return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
+      // XXX This isn't the right error
+      return NS_ERROR_DOM_TYPE_ERR;
     }
 
     NS_ASSERTION(JSVAL_IS_OBJECT(aOptions), "Huh?!");
     JSObject* options = JSVAL_TO_OBJECT(aOptions);
 
-    js::AutoIdArray ids(aCx, JS_Enumerate(aCx, options));
-    if (!ids) {
+    jsval val;
+    if (!JS_GetPropertyById(aCx, options, nsDOMClassInfo::sKeyPath_id, &val)) {
+      NS_WARNING("JS_GetPropertyById failed!");
       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
 
-    for (size_t index = 0; index < ids.length(); index++) {
-      jsid id = ids[index];
-
-      if (id != nsDOMClassInfo::sKeyPath_id &&
-          id != nsDOMClassInfo::sAutoIncrement_id) {
-        // XXX Update spec for a real code here
-        return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
+    if (!JSVAL_IS_VOID(val) && !JSVAL_IS_NULL(val)) {
+      JSString* str = JS_ValueToString(aCx, val);
+      if (!str) {
+        NS_WARNING("JS_ValueToString failed!");
+        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
       }
-
-      jsval val;
-      if (!JS_GetPropertyById(aCx, options, id, &val)) {
-        NS_WARNING("JS_GetPropertyById failed!");
+      nsDependentJSString dependentKeyPath;
+      if (!dependentKeyPath.init(aCx, str)) {
+        NS_WARNING("Initializing keyPath failed!");
         return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
       }
+      keyPath = dependentKeyPath;
+    }
 
-      if (id == nsDOMClassInfo::sKeyPath_id) {
-        JSString* str = JS_ValueToString(aCx, val);
-        if (!str) {
-          NS_WARNING("JS_ValueToString failed!");
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-        }
-        nsDependentJSString dependentKeyPath;
-        if (!dependentKeyPath.init(aCx, str)) {
-          NS_WARNING("Initializing keyPath failed!");
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-        }
-        keyPath = dependentKeyPath;
-      }
-      else if (id == nsDOMClassInfo::sAutoIncrement_id) {
-        JSBool boolVal;
-        if (!JS_ValueToBoolean(aCx, val, &boolVal)) {
-          NS_WARNING("JS_ValueToBoolean failed!");
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-        }
-        autoIncrement = !!boolVal;
-      }
-      else {
-        NS_NOTREACHED("Shouldn't be able to get here!");
-      }
+    if (!JS_GetPropertyById(aCx, options, nsDOMClassInfo::sAutoIncrement_id,
+                            &val)) {
+      NS_WARNING("JS_GetPropertyById failed!");
+      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
+
+    JSBool boolVal;
+    if (!JS_ValueToBoolean(aCx, val, &boolVal)) {
+      NS_WARNING("JS_ValueToBoolean failed!");
+      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    }
+    autoIncrement = !!boolVal;
   }
 
   nsAutoPtr<ObjectStoreInfo> newInfo(new ObjectStoreInfo());
 
   newInfo->name = aName;
   newInfo->id = databaseInfo->nextObjectStoreId++;
   newInfo->keyPath = keyPath;
   newInfo->autoIncrement = autoIncrement;
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1297,54 +1297,35 @@ IDBObjectStore::CreateIndex(const nsAStr
 
   NS_ASSERTION(mTransaction->IsOpen(), "Impossible!");
 
   bool unique = false;
 
   // Get optional arguments.
   if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) {
     if (JSVAL_IS_PRIMITIVE(aOptions)) {
-    // XXX Update spec for a real code here
-      return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
+      // XXX Update spec for a real code here
+      return NS_ERROR_DOM_TYPE_ERR;
     }
 
     NS_ASSERTION(JSVAL_IS_OBJECT(aOptions), "Huh?!");
     JSObject* options = JSVAL_TO_OBJECT(aOptions);
 
-    js::AutoIdArray ids(aCx, JS_Enumerate(aCx, options));
-    if (!ids) {
+    jsval val;
+    if (!JS_GetPropertyById(aCx, options, nsDOMClassInfo::sUnique_id, &val)) {
+      NS_WARNING("JS_GetPropertyById failed!");
       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
 
-    for (size_t index = 0; index < ids.length(); index++) {
-      jsid id = ids[index];
-
-      if (id != nsDOMClassInfo::sUnique_id) {
-        // XXX Update spec for a real code here
-        return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
-      }
-
-      jsval val;
-      if (!JS_GetPropertyById(aCx, options, id, &val)) {
-        NS_WARNING("JS_GetPropertyById failed!");
-        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-      }
-
-      if (id == nsDOMClassInfo::sUnique_id) {
-        JSBool boolVal;
-        if (!JS_ValueToBoolean(aCx, val, &boolVal)) {
-          NS_WARNING("JS_ValueToBoolean failed!");
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-        }
-        unique = !!boolVal;
-      }
-      else {
-        NS_NOTREACHED("Shouldn't be able to get here!");
-      }
+    JSBool boolVal;
+    if (!JS_ValueToBoolean(aCx, val, &boolVal)) {
+      NS_WARNING("JS_ValueToBoolean failed!");
+      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
+    unique = !!boolVal;
   }
 
   DatabaseInfo* databaseInfo = mTransaction->Database()->Info();
 
   IndexInfo* indexInfo = info->indexes.AppendElement();
   if (!indexInfo) {
     NS_WARNING("Out of memory!");
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
--- a/dom/indexedDB/test/test_add_twice_failure.html
+++ b/dom/indexedDB/test/test_add_twice_failure.html
@@ -19,17 +19,17 @@
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = request.result;
 
       ok(event.target === request, "Good event target");
 
-      let objectStore = db.createObjectStore("foo", { keyPath: "" });
+      let objectStore = db.createObjectStore("foo", { keyPath: null });
       let key = 10;
 
       request = objectStore.add({}, key);
       request.onerror = errorHandler;
       request.onsuccess = grabEventAndContinueHandler;
       event = yield;
 
       is(request.result, key, "Correct key");
--- a/dom/indexedDB/test/test_create_index.html
+++ b/dom/indexedDB/test/test_create_index.html
@@ -53,23 +53,19 @@
         try {
           request = objectStore.createIndex("foo", "bar", 10);
           ok(false, "createIndex with bad options should throw");
         }
         catch(e) {
           ok(true, "createIndex with bad options threw");
         }
 
-        try {
-          request = objectStore.createIndex("foo", "bar", { foo: "" });
-          ok(false, "createIndex with bad options should throw");
-        }
-        catch(e) {
-          ok(true, "createIndex with bad options threw");
-        }
+        ok(objectStore.createIndex("foo", "bar", { foo: "" }),
+           "createIndex with unknown options should not throw");
+        objectStore.deleteIndex("foo");
 
         // Test index creation, and that it ends up in indexNames.
         let objectStoreName = info.name;
         for (let j = 0; j < indexInfo.length; j++) {
           let info = indexInfo[j];
           let count = objectStore.indexNames.length;
           let index = info.hasOwnProperty("options") ?
                       objectStore.createIndex(info.name, info.keyPath,
--- a/dom/indexedDB/test/test_create_objectStore.html
+++ b/dom/indexedDB/test/test_create_objectStore.html
@@ -13,20 +13,20 @@
     function testSteps()
     {
       const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
       const nsIIDBTransaction = Components.interfaces.nsIIDBTransaction;
 
       const name = window.location.pathname;
       const description = "My Test Database";
       const objectStoreInfo = [
-        { name: "1", options: { keyPath: "" } },
-        { name: "2", options: { keyPath: "", autoIncrement: true } },
-        { name: "3", options: { keyPath: "", autoIncrement: false } },
-        { name: "4", options: { keyPath: "" } },
+        { name: "1", options: { keyPath: null } },
+        { name: "2", options: { keyPath: null, autoIncrement: true } },
+        { name: "3", options: { keyPath: null, autoIncrement: false } },
+        { name: "4", options: { keyPath: null } },
         { name: "5", options: { keyPath: "foo" } },
         { name: "6" },
         { name: "7", options: null },
         { name: "8", options: { autoIncrement: true } },
         { name: "9", options: { autoIncrement: false } },
         { name: "10", options: { keyPath: "foo", autoIncrement: false } },
         { name: "11", options: { keyPath: "foo", autoIncrement: true } },
         { name: "" },
@@ -47,23 +47,19 @@
       try {
         db.createObjectStore("foo", "bar");
         ok(false, "createObjectStore with bad options should throw");
       }
       catch(e) {
         ok(true, "createObjectStore with bad options");
       }
 
-      try {
-        db.createObjectStore("foo", { foo: "" });
-        ok(false, "createObjectStore with bad options should throw");
-      }
-      catch(e) {
-        ok(true, "createObjectStore with bad options");
-      }
+      ok(db.createObjectStore("foo", { foo: "" }),
+         "createObjectStore with unknown options should not throw");
+      db.deleteObjectStore("foo");
 
       for (let index in objectStoreInfo) {
         index = parseInt(index);
         const info = objectStoreInfo[index];
 
         let objectStore = info.hasOwnProperty("options") ?
                           db.createObjectStore(info.name, info.options) :
                           db.createObjectStore(info.name);
--- a/dom/indexedDB/test/test_cursor_update_updates_indexes.html
+++ b/dom/indexedDB/test/test_cursor_update_updates_indexes.html
@@ -15,21 +15,21 @@
       const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
       const nsIIDBTransaction = Components.interfaces.nsIIDBTransaction;
 
       const name = window.location.pathname;
       const description = "My Test Database";
       const START_DATA = "hi";
       const END_DATA = "bye";
       const objectStoreInfo = [
-        { name: "1", options: { keyPath: "" }, key: 1,
+        { name: "1", options: { keyPath: null }, key: 1,
           entry: { data: START_DATA } },
         { name: "2", options: { keyPath: "foo" },
           entry: { foo: 1, data: START_DATA } },
-        { name: "3", options: { keyPath: "", autoIncrement: true },
+        { name: "3", options: { keyPath: null, autoIncrement: true },
           entry: { data: START_DATA } },
         { name: "4", options: { keyPath: "foo", autoIncrement: true },
           entry: { data: START_DATA } },
       ];
 
       for (let i = 0; i < objectStoreInfo.length; i++) {
         // Create our object stores.
         let info = objectStoreInfo[i];
--- a/dom/indexedDB/test/test_indexes.html
+++ b/dom/indexedDB/test/test_indexes.html
@@ -71,17 +71,17 @@
       let request = mozIndexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
-      let objectStore = db.createObjectStore(objectStoreName, { keyPath: "" });
+      let objectStore = db.createObjectStore(objectStoreName, { 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) {
--- a/dom/indexedDB/test/test_objectStore_remove_values.html
+++ b/dom/indexedDB/test/test_objectStore_remove_values.html
@@ -35,17 +35,17 @@ function testSteps()
       autoIncrement: true,
       storedObject: {name: "Lincoln"},
       keyName: undefined,
       keyValue: undefined,
     },
     { name: "out of line key; no key generator",
       autoIncrement: false,
       storedObject: {name: "Lincoln"},
-      keyName: "",
+      keyName: null,
       keyValue: 1,
     }
   ];
 
   for (let i = 0; i < data.length; i++) {
     let test = data[i];
 
     let request = mozIndexedDB.open(name, i+1, description);