Changeset 118011 in webkit


Ignore:
Timestamp:
May 22, 2012 11:46:07 AM (12 years ago)
Author:
jsbell@chromium.org
Message:

IndexedDB: Support Array-type key paths
https://bugs.webkit.org/show_bug.cgi?id=84207

Reviewed by Tony Chang.

Source/WebCore:

Implement IDB spec behavior that key paths can be arrays of strings; when
evaluated, these yield arrays of keys, providing compound key support. Also
changes exception types to match the spec.

Test: storage/indexeddb/keypath-arrays.html
Test: storage/indexeddb/keypath-basics.html

  • Modules/indexeddb/IDBDatabase.cpp:

(WebCore::IDBDatabase::createObjectStore): Look for both string and array in option dict,
throw exceptions for forbidden combinations of key generator and key paths.

  • Modules/indexeddb/IDBObjectStore.cpp:

(WebCore::IDBObjectStore::createIndex): Handle special cases (accepted and forbidden).
(WebCore):

  • Modules/indexeddb/IDBObjectStore.h:

(IDBObjectStore):
(WebCore::IDBObjectStore::createIndex): Overloads to satisfy IDL overloads and optional dicts.

  • Modules/indexeddb/IDBObjectStore.idl: Add DOMString array overload.
  • bindings/v8/IDBBindingUtilities.cpp: Implement spec logic for evaluating array key paths.

(WebCore::createIDBKeyFromSerializedValueAndKeyPath):
(WebCore):

LayoutTests:

  • storage/indexeddb/keypath-arrays-expected.txt: Added.
  • storage/indexeddb/keypath-arrays.html: Added.
  • storage/indexeddb/keypath-basics-expected.txt:
  • storage/indexeddb/mozilla/create-objectstore-basics-expected.txt:
  • storage/indexeddb/mozilla/resources/create-objectstore-basics.js:

(cleanDatabase):

  • storage/indexeddb/objectStore-required-arguments-expected.txt:
  • storage/indexeddb/resources/keypath-arrays.js: Added.

(test.request.onsuccess):
(test):
(openSuccess.request.onsuccess):
(openSuccess):
(testKeyPaths.checkStore.request.onsuccess):
(testKeyPaths.checkStore):
(testKeyPaths.checkIndex.request.onsuccess):
(testKeyPaths.checkIndex):
(testKeyPaths):

  • storage/indexeddb/resources/keypath-basics.js:
Location:
trunk
Files:
3 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r118005 r118011  
     12012-05-22  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Support Array-type key paths
     4        https://bugs.webkit.org/show_bug.cgi?id=84207
     5
     6        Reviewed by Tony Chang.
     7
     8        * storage/indexeddb/keypath-arrays-expected.txt: Added.
     9        * storage/indexeddb/keypath-arrays.html: Added.
     10        * storage/indexeddb/keypath-basics-expected.txt:
     11        * storage/indexeddb/mozilla/create-objectstore-basics-expected.txt:
     12        * storage/indexeddb/mozilla/resources/create-objectstore-basics.js:
     13        (cleanDatabase):
     14        * storage/indexeddb/objectStore-required-arguments-expected.txt:
     15        * storage/indexeddb/resources/keypath-arrays.js: Added.
     16        (test.request.onsuccess):
     17        (test):
     18        (openSuccess.request.onsuccess):
     19        (openSuccess):
     20        (testKeyPaths.checkStore.request.onsuccess):
     21        (testKeyPaths.checkStore):
     22        (testKeyPaths.checkIndex.request.onsuccess):
     23        (testKeyPaths.checkIndex):
     24        (testKeyPaths):
     25        * storage/indexeddb/resources/keypath-basics.js:
     26
    1272012-05-22  Abhishek Arya  <inferno@chromium.org>
    228
  • trunk/LayoutTests/storage/indexeddb/keypath-basics-expected.txt

    r117817 r118011  
    99db = event.target.result
    1010request = db.setVersion('1')
     11
     12testValidKeyPaths():
    1113Deleted all object stores.
    1214store = db.createObjectStore('name')
     
    3840PASS index.keyPath is 'foo.bar.baz'
    3941Deleted all object stores.
     42
     43testInvalidKeyPaths():
    4044Deleted all object stores.
    41 globalKeyPath = '[]'
    42 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     45
     46Object store key path may not be empty or an array if autoIncrement is true
     47Expecting exception from store = db.createObjectStore('storeName', {autoIncrement: true, keyPath: ''})
    4348PASS Exception was thrown.
    44 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     49PASS code is DOMException.INVALID_ACCESS_ERR
    4550Deleted all object stores.
    46 globalKeyPath = '["foo"]'
    47 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     51Expecting exception from store = db.createObjectStore('storeName', {autoIncrement: true, keyPath: []})
    4852PASS Exception was thrown.
    49 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     53PASS code is DOMException.INVALID_ACCESS_ERR
    5054Deleted all object stores.
    51 globalKeyPath = '["foo", "bar"]'
    52 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     55Expecting exception from store = db.createObjectStore('storeName', {autoIncrement: true, keyPath: ['a']})
    5356PASS Exception was thrown.
    54 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     57PASS code is DOMException.INVALID_ACCESS_ERR
    5558Deleted all object stores.
    56 globalKeyPath = '["", ""]'
    57 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     59Expecting exception from store = db.createObjectStore('storeName', {autoIncrement: true, keyPath: ['']})
    5860PASS Exception was thrown.
    59 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     61PASS code is DOMException.INVALID_ACCESS_ERR
    6062Deleted all object stores.
    61 globalKeyPath = '[1.0, 2.0]'
    62 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     63
     64Key paths which are never valid:
     65Expecting exception from db.createObjectStore('name', {keyPath: ' '})
    6366PASS Exception was thrown.
    64 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     67PASS code is DOMException.SYNTAX_ERR
     68Expecting exception from db.createObjectStore('name').createIndex('name', ' ')
     69PASS Exception was thrown.
     70PASS code is DOMException.SYNTAX_ERR
    6571Deleted all object stores.
    66 globalKeyPath = '[["foo"]]'
    67 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     72Expecting exception from db.createObjectStore('name', {keyPath: 'foo '})
    6873PASS Exception was thrown.
    69 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     74PASS code is DOMException.SYNTAX_ERR
     75Expecting exception from db.createObjectStore('name').createIndex('name', 'foo ')
     76PASS Exception was thrown.
     77PASS code is DOMException.SYNTAX_ERR
    7078Deleted all object stores.
    71 globalKeyPath = '["foo", ["bar"]]'
    72 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     79Expecting exception from db.createObjectStore('name', {keyPath: 'foo bar'})
    7380PASS Exception was thrown.
    74 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     81PASS code is DOMException.SYNTAX_ERR
     82Expecting exception from db.createObjectStore('name').createIndex('name', 'foo bar')
     83PASS Exception was thrown.
     84PASS code is DOMException.SYNTAX_ERR
    7585Deleted all object stores.
    76 globalKeyPath = ' '
    77 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     86Expecting exception from db.createObjectStore('name', {keyPath: 'foo. bar'})
    7887PASS Exception was thrown.
    79 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     88PASS code is DOMException.SYNTAX_ERR
     89Expecting exception from db.createObjectStore('name').createIndex('name', 'foo. bar')
     90PASS Exception was thrown.
     91PASS code is DOMException.SYNTAX_ERR
    8092Deleted all object stores.
    81 globalKeyPath = 'foo '
    82 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     93Expecting exception from db.createObjectStore('name', {keyPath: 'foo .bar'})
    8394PASS Exception was thrown.
    84 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     95PASS code is DOMException.SYNTAX_ERR
     96Expecting exception from db.createObjectStore('name').createIndex('name', 'foo .bar')
     97PASS Exception was thrown.
     98PASS code is DOMException.SYNTAX_ERR
    8599Deleted all object stores.
    86 globalKeyPath = 'foo bar'
    87 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     100Expecting exception from db.createObjectStore('name', {keyPath: 'foo..bar'})
    88101PASS Exception was thrown.
    89 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     102PASS code is DOMException.SYNTAX_ERR
     103Expecting exception from db.createObjectStore('name').createIndex('name', 'foo..bar')
     104PASS Exception was thrown.
     105PASS code is DOMException.SYNTAX_ERR
    90106Deleted all object stores.
    91 globalKeyPath = 'foo. bar'
    92 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     107Expecting exception from db.createObjectStore('name', {keyPath: '+foo'})
    93108PASS Exception was thrown.
    94 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     109PASS code is DOMException.SYNTAX_ERR
     110Expecting exception from db.createObjectStore('name').createIndex('name', '+foo')
     111PASS Exception was thrown.
     112PASS code is DOMException.SYNTAX_ERR
    95113Deleted all object stores.
    96 globalKeyPath = 'foo .bar'
    97 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     114Expecting exception from db.createObjectStore('name', {keyPath: 'foo%'})
    98115PASS Exception was thrown.
    99 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     116PASS code is DOMException.SYNTAX_ERR
     117Expecting exception from db.createObjectStore('name').createIndex('name', 'foo%')
     118PASS Exception was thrown.
     119PASS code is DOMException.SYNTAX_ERR
    100120Deleted all object stores.
    101 globalKeyPath = 'foo..bar'
    102 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     121Expecting exception from db.createObjectStore('name', {keyPath: '1'})
    103122PASS Exception was thrown.
    104 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     123PASS code is DOMException.SYNTAX_ERR
     124Expecting exception from db.createObjectStore('name').createIndex('name', '1')
     125PASS Exception was thrown.
     126PASS code is DOMException.SYNTAX_ERR
    105127Deleted all object stores.
    106 globalKeyPath = '+foo'
    107 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     128Expecting exception from db.createObjectStore('name', {keyPath: '1.0'})
    108129PASS Exception was thrown.
    109 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    110 Deleted all object stores.
    111 globalKeyPath = 'foo%'
    112 Expecting exception from db.createObjectStore('name', {keyPath: globalKeyPath})
     130PASS code is DOMException.SYNTAX_ERR
     131Expecting exception from db.createObjectStore('name').createIndex('name', '1.0')
    113132PASS Exception was thrown.
    114 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    115 Deleted all object stores.
    116 globalKeyPath = ' '
    117 store = db.createObjectStore('storeName')
    118 Expecting exception from store.createIndex('name', globalKeyPath)
    119 PASS Exception was thrown.
    120 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    121 Deleted all object stores.
    122 globalKeyPath = 'foo '
    123 store = db.createObjectStore('storeName')
    124 Expecting exception from store.createIndex('name', globalKeyPath)
    125 PASS Exception was thrown.
    126 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    127 Deleted all object stores.
    128 globalKeyPath = 'foo bar'
    129 store = db.createObjectStore('storeName')
    130 Expecting exception from store.createIndex('name', globalKeyPath)
    131 PASS Exception was thrown.
    132 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    133 Deleted all object stores.
    134 globalKeyPath = 'foo. bar'
    135 store = db.createObjectStore('storeName')
    136 Expecting exception from store.createIndex('name', globalKeyPath)
    137 PASS Exception was thrown.
    138 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    139 Deleted all object stores.
    140 globalKeyPath = 'foo .bar'
    141 store = db.createObjectStore('storeName')
    142 Expecting exception from store.createIndex('name', globalKeyPath)
    143 PASS Exception was thrown.
    144 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    145 Deleted all object stores.
    146 globalKeyPath = 'foo..bar'
    147 store = db.createObjectStore('storeName')
    148 Expecting exception from store.createIndex('name', globalKeyPath)
    149 PASS Exception was thrown.
    150 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    151 Deleted all object stores.
    152 globalKeyPath = '+foo'
    153 store = db.createObjectStore('storeName')
    154 Expecting exception from store.createIndex('name', globalKeyPath)
    155 PASS Exception was thrown.
    156 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
    157 Deleted all object stores.
    158 globalKeyPath = 'foo%'
    159 store = db.createObjectStore('storeName')
    160 Expecting exception from store.createIndex('name', globalKeyPath)
    161 PASS Exception was thrown.
    162 PASS code is IDBDatabaseException.NON_TRANSIENT_ERR
     133PASS code is DOMException.SYNTAX_ERR
    163134Deleted all object stores.
    164135PASS successfullyParsed is true
  • trunk/LayoutTests/storage/indexeddb/mozilla/create-objectstore-basics-expected.txt

    r116337 r118011  
    1414PASS objectStore.indexNames.length is 0
    1515PASS event.target.transaction.db is db
    16 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    17 PASS event.target.transaction.mode is 'versionchange'
     16PASS event.target.transaction.mode is "versionchange"
    1817objectStore = db.createObjectStore(info.name, info.options);
    1918PASS objectStore.name is info.name
    2019PASS objectStore.indexNames.length is 0
    2120PASS event.target.transaction.db is db
    22 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    23 PASS event.target.transaction.mode is 'versionchange'
     21PASS event.target.transaction.mode is "versionchange"
    2422objectStore = db.createObjectStore(info.name, info.options);
    2523PASS objectStore.name is info.name
    2624PASS objectStore.indexNames.length is 0
    2725PASS event.target.transaction.db is db
    28 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    29 PASS event.target.transaction.mode is 'versionchange'
     26PASS event.target.transaction.mode is "versionchange"
     27Expecting exception from objectStore = db.createObjectStore(info.name, info.options)
     28PASS Exception was thrown.
     29PASS code is DOMException.INVALID_ACCESS_ERR
    3030objectStore = db.createObjectStore(info.name, info.options);
    3131PASS objectStore.name is info.name
    3232PASS objectStore.indexNames.length is 0
    3333PASS event.target.transaction.db is db
    34 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    35 PASS event.target.transaction.mode is 'versionchange'
    36 objectStore = db.createObjectStore(info.name, info.options);
    37 PASS objectStore.name is info.name
    38 PASS objectStore.indexNames.length is 0
    39 PASS event.target.transaction.db is db
    40 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    41 PASS event.target.transaction.mode is 'versionchange'
     34PASS event.target.transaction.mode is "versionchange"
    4235objectStore = db.createObjectStore(info.name, info.options);
    4336PASS objectStore.name is info.name
     
    4538PASS objectStore.indexNames.length is 0
    4639PASS event.target.transaction.db is db
    47 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    48 PASS event.target.transaction.mode is 'versionchange'
     40PASS event.target.transaction.mode is "versionchange"
    4941objectStore = db.createObjectStore(info.name, info.options);
    5042PASS objectStore.name is info.name
     
    5244PASS objectStore.indexNames.length is 0
    5345PASS event.target.transaction.db is db
    54 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    55 PASS event.target.transaction.mode is 'versionchange'
     46PASS event.target.transaction.mode is "versionchange"
    5647objectStore = db.createObjectStore(info.name, info.options);
    5748PASS objectStore.name is info.name
     
    5950PASS objectStore.indexNames.length is 0
    6051PASS event.target.transaction.db is db
    61 PASS event.target.transaction.readyState is IDBTransaction.LOADING
    62 PASS event.target.transaction.mode is 'versionchange'
     52PASS event.target.transaction.mode is "versionchange"
    6353PASS successfullyParsed is true
    6454
  • trunk/LayoutTests/storage/indexeddb/mozilla/resources/create-objectstore-basics.js

    r116337 r118011  
    4040        { name: "2", options: { autoIncrement: false } },
    4141        { name: "3", options: { keyPath: "" } },
    42         { name: "4", options: { keyPath: "", autoIncrement: true } },
     42        { name: "4", options: { keyPath: "", autoIncrement: true }, fail: true },
    4343        { name: "5", options: { keyPath: "", autoIncrement: false } },
    4444        { name: "6", options: { keyPath: "foo" } },
     
    5050        index = parseInt(index);
    5151        info = objectStoreInfo[index];
    52         objectStore = evalAndLog("objectStore = db.createObjectStore(info.name, info.options);");
    53         shouldBe("objectStore.name", "info.name");
    54         if (info.options && info.options.keyPath) {
    55             shouldBe("objectStore.keyPath", "info.options.keyPath");
     52        if (!info.fail) {
     53            objectStore = evalAndLog("objectStore = db.createObjectStore(info.name, info.options);");
     54            shouldBe("objectStore.name", "info.name");
     55            if (info.options && info.options.keyPath) {
     56                shouldBe("objectStore.keyPath", "info.options.keyPath");
     57            }
     58            shouldBe("objectStore.indexNames.length", "0");
     59            shouldBe("event.target.transaction.db", "db");
     60            shouldBeEqualToString("event.target.transaction.mode", "versionchange");
     61        } else {
     62            evalAndExpectException("objectStore = db.createObjectStore(info.name, info.options)", "DOMException.INVALID_ACCESS_ERR");
    5663        }
    57         shouldBe("objectStore.indexNames.length", "0");
    58         shouldBe("event.target.transaction.db", "db");
    59         shouldBe("event.target.transaction.readyState", "IDBTransaction.LOADING");
    60         shouldBe("event.target.transaction.mode", "'versionchange'");
    6164    }
    6265
  • trunk/LayoutTests/storage/indexeddb/objectStore-required-arguments-expected.txt

    r114805 r118011  
    1515PASS objectStore.delete(); threw exception TypeError: Type error.
    1616PASS objectStore.get(); threw exception TypeError: Type error.
    17 PASS objectStore.createIndex(); threw exception TypeError: Not enough arguments.
    18 PASS objectStore.createIndex('foo'); threw exception TypeError: Not enough arguments.
     17PASS objectStore.createIndex(); threw exception TypeError: Type error.
     18PASS objectStore.createIndex('foo'); threw exception TypeError: Type error.
    1919PASS objectStore.index(); threw exception TypeError: Not enough arguments.
    2020PASS objectStore.deleteIndex(); threw exception TypeError: Not enough arguments.
  • trunk/LayoutTests/storage/indexeddb/resources/keypath-basics.js

    r117817 r118011  
    2626function testValidKeyPaths()
    2727{
     28    debug("");
     29    debug("testValidKeyPaths():");
    2830    deleteAllObjectStores(db);
    2931
     
    5355function testInvalidKeyPaths()
    5456{
     57    debug("");
     58    debug("testInvalidKeyPaths():");
    5559    deleteAllObjectStores(db);
    5660
    57     testKeyPaths = ['[]', '["foo"]', '["foo", "bar"]', '["", ""]', '[1.0, 2.0]', '[["foo"]]', '["foo", ["bar"]]'];
     61    debug("");
     62    debug("Object store key path may not be empty or an array if autoIncrement is true");
     63    testKeyPaths = ["''", "[]", "['a']", "['']"];
    5864    testKeyPaths.forEach(function (keyPath) {
    59         globalKeyPath = keyPath;
    60         debug("globalKeyPath = '" + globalKeyPath + "'");
    61         evalAndExpectException("db.createObjectStore('name', {keyPath: globalKeyPath})", "IDBDatabaseException.NON_TRANSIENT_ERR");
     65        store = evalAndExpectException("store = db.createObjectStore('storeName', {autoIncrement: true, keyPath: " + keyPath + "})", "DOMException.INVALID_ACCESS_ERR");
    6266        deleteAllObjectStores(db);
    6367    });
    6468
    65     testKeyPaths = [' ', 'foo ', 'foo bar', 'foo. bar', 'foo .bar', 'foo..bar', '+foo', 'foo%'];
     69    debug("");
     70    debug("Key paths which are never valid:");
     71    testKeyPaths = ["' '", "'foo '", "'foo bar'", "'foo. bar'", "'foo .bar'", "'foo..bar'", "'+foo'", "'foo%'", "'1'", "'1.0'"];
    6672    testKeyPaths.forEach(function (keyPath) {
    67         globalKeyPath = keyPath;
    68         debug("globalKeyPath = '" + globalKeyPath + "'");
    69         evalAndExpectException("db.createObjectStore('name', {keyPath: globalKeyPath})", "IDBDatabaseException.NON_TRANSIENT_ERR");
    70         deleteAllObjectStores(db);
    71     });
    72 
    73     testKeyPaths = [' ', 'foo ', 'foo bar', 'foo. bar', 'foo .bar', 'foo..bar', '+foo', 'foo%'];
    74     testKeyPaths.forEach(function (keyPath) {
    75         globalKeyPath = keyPath;
    76         debug("globalKeyPath = '" + globalKeyPath + "'");
    77         store = evalAndLog("store = db.createObjectStore('storeName')");
    78         evalAndExpectException("store.createIndex('name', globalKeyPath)", "IDBDatabaseException.NON_TRANSIENT_ERR");
     73        evalAndExpectException("db.createObjectStore('name', {keyPath: " + keyPath + "})", "DOMException.SYNTAX_ERR");
     74        evalAndExpectException("db.createObjectStore('name').createIndex('name', " + keyPath + ")", "DOMException.SYNTAX_ERR");
    7975        deleteAllObjectStores(db);
    8076    });
  • trunk/Source/WebCore/ChangeLog

    r118010 r118011  
     12012-05-22  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Support Array-type key paths
     4        https://bugs.webkit.org/show_bug.cgi?id=84207
     5
     6        Reviewed by Tony Chang.
     7
     8        Implement IDB spec behavior that key paths can be arrays of strings; when
     9        evaluated, these yield arrays of keys, providing compound key support. Also
     10        changes exception types to match the spec.
     11
     12        Test: storage/indexeddb/keypath-arrays.html
     13        Test: storage/indexeddb/keypath-basics.html
     14
     15        * Modules/indexeddb/IDBDatabase.cpp:
     16        (WebCore::IDBDatabase::createObjectStore): Look for both string and array in option dict,
     17        throw exceptions for forbidden combinations of key generator and key paths.
     18        * Modules/indexeddb/IDBObjectStore.cpp:
     19        (WebCore::IDBObjectStore::createIndex): Handle special cases (accepted and forbidden).
     20        (WebCore):
     21        * Modules/indexeddb/IDBObjectStore.h:
     22        (IDBObjectStore):
     23        (WebCore::IDBObjectStore::createIndex): Overloads to satisfy IDL overloads and optional dicts.
     24        * Modules/indexeddb/IDBObjectStore.idl: Add DOMString array overload.
     25        * bindings/v8/IDBBindingUtilities.cpp: Implement spec logic for evaluating array key paths.
     26        (WebCore::createIDBKeyFromSerializedValueAndKeyPath):
     27        (WebCore):
     28
    1292012-05-22  Martin Robinson  <mrobinson@igalia.com>
    230
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp

    r117817 r118011  
    9696    if (!options.isUndefinedOrNull()) {
    9797        String keyPathString;
    98         if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString))
     98        Vector<String> keyPathArray;
     99        if (options.get("keyPath", keyPathArray))
     100            keyPath = IDBKeyPath(keyPathArray);
     101        else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString))
    99102            keyPath = IDBKeyPath(keyPathString);
    100103    }
    101104
    102105    if (!keyPath.isNull() && !keyPath.isValid()) {
    103         ec = IDBDatabaseException::NON_TRANSIENT_ERR;
     106        ec = SYNTAX_ERR;
    104107        return 0;
    105108    }
    106109
    107110    bool autoIncrement = false;
    108     options.get("autoIncrement", autoIncrement);
    109     // FIXME: Look up evictable and pass that on as well.
     111    if (!options.isUndefinedOrNull())
     112        options.get("autoIncrement", autoIncrement);
     113
     114    if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) {
     115        ec = INVALID_ACCESS_ERR;
     116        return 0;
     117    }
    110118
    111119    RefPtr<IDBObjectStoreBackendInterface> objectStoreBackend = m_backend->createObjectStore(name, keyPath, autoIncrement, m_versionChangeTransaction->backend(), ec);
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

    r117817 r118011  
    215215}
    216216
     217PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary& options, ExceptionCode& ec)
     218{
     219    // FIXME: Binding code for DOMString[] should not match null. http://webkit.org/b/84217
     220    if (!keyPath)
     221        return createIndex(name, IDBKeyPath("null"), options, ec);
     222    return createIndex(name, IDBKeyPath(*keyPath), options, ec);
     223}
     224
     225
    217226PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKeyPath& keyPath, const Dictionary& options, ExceptionCode& ec)
    218227{
    219228    IDB_TRACE("IDBObjectStore::createIndex");
    220229    if (!keyPath.isValid()) {
    221         ec = IDBDatabaseException::NON_TRANSIENT_ERR;
     230        ec = SYNTAX_ERR;
    222231        return 0;
    223232    }
     
    229238    options.get("multiEntry", multiEntry);
    230239
    231     // FIXME: When Array-type keyPaths are supported, throw exception if keyPath is Array and multiEntry is true.
     240    if (keyPath.type() == IDBKeyPath::ArrayType && multiEntry) {
     241        ec = NOT_SUPPORTED_ERR;
     242        return 0;
     243    }
    232244
    233245    RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->createIndex(name, keyPath, unique, multiEntry, m_transaction->backend(), ec);
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h

    r117817 r118011  
    6363    bool autoIncrement() const;
    6464
    65     // FIXME: Try to modify the code generator so this is unneeded.
    6665    PassRefPtr<IDBRequest> add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return add(context, value, 0, ec);  }
    6766    PassRefPtr<IDBRequest> put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return put(context, value, 0, ec);  }
    68     PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, ExceptionCode& ec) { return createIndex(name, keyPath, Dictionary(), ec); }
    6967    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCode& ec) { return openCursor(context, static_cast<IDBKeyRange*>(0), ec); }
    7068    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) { return openCursor(context, keyRange, IDBCursor::directionNext(), ec); }
     
    7977    PassRefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&);
    8078
     79    // FIXME: Try to modify the code generator so this duplication is unneeded.
    8180    PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, const Dictionary&, ExceptionCode&);
     81    PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, ExceptionCode& ec) { return createIndex(name, keyPath, Dictionary(), ec); }
     82    PassRefPtr<IDBIndex> createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary&, ExceptionCode&);
     83    PassRefPtr<IDBIndex> createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, ExceptionCode& ec) { return createIndex(name, keyPath, Dictionary(), ec); }
    8284    PassRefPtr<IDBIndex> createIndex(const String&, const IDBKeyPath&, const Dictionary&, ExceptionCode&);
    8385
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl

    r117817 r118011  
    6060            raises (IDBDatabaseException);
    6161
     62        IDBIndex createIndex(in DOMString name, in DOMString[] keyPath, in [Optional] Dictionary options)
     63            raises (IDBDatabaseException);
    6264        IDBIndex createIndex(in DOMString name, in DOMString keyPath, in [Optional] Dictionary options)
    6365            raises (IDBDatabaseException);
  • trunk/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp

    r117817 r118011  
    154154} // anonymous namespace
    155155
    156 PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
     156static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const String& keyPath)
     157{
     158    Vector<String> keyPathElements;
     159    IDBKeyPathParseError error;
     160    IDBParseKeyPath(keyPath, keyPathElements, error);
     161    ASSERT(error == IDBKeyPathParseErrorNone);
     162
     163    V8AuxiliaryContext context;
     164    v8::Handle<v8::Value> v8Value(value->deserialize());
     165    v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size()));
     166    if (v8Key.IsEmpty())
     167        return 0;
     168    return createIDBKeyFromValue(v8Key);
     169}
     170
     171
     172PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const IDBKeyPath& keyPath)
    157173{
    158174    IDB_TRACE("createIDBKeyFromSerializedValueAndKeyPath");
     175    ASSERT(!keyPath.isNull());
     176
     177    RefPtr<SerializedScriptValue> value = prpValue;
     178
     179    if (keyPath.type() == IDBKeyPath::ArrayType) {
     180        IDBKey::KeyArray result;
     181        const Vector<String>& array = keyPath.array();
     182        for (size_t i = 0; i < array.size(); ++i) {
     183            RefPtr<IDBKey> key = createIDBKeyFromSerializedValueAndKeyPath(value, array[i]);
     184            if (!key)
     185                return 0;
     186            result.append(key);
     187        }
     188        return IDBKey::createArray(result);
     189    }
     190
     191    ASSERT(keyPath.type() == IDBKeyPath::StringType);
     192    return createIDBKeyFromSerializedValueAndKeyPath(value, keyPath.string());
     193}
     194
     195PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
     196{
     197    IDB_TRACE("injectIDBKeyIntoSerializedValue");
     198
    159199    ASSERT(keyPath.type() == IDBKeyPath::StringType);
    160200    Vector<String> keyPathElements;
     
    163203    ASSERT(error == IDBKeyPathParseErrorNone);
    164204
    165     V8AuxiliaryContext context;
    166     v8::Handle<v8::Value> v8Value(value->deserialize());
    167     v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size()));
    168     if (v8Key.IsEmpty())
    169         return 0;
    170     return createIDBKeyFromValue(v8Key);
    171 }
    172 
    173 PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
    174 {
    175     IDB_TRACE("injectIDBKeyIntoSerializedValue");
    176 
    177     ASSERT(keyPath.type() == IDBKeyPath::StringType);
    178     Vector<String> keyPathElements;
    179     IDBKeyPathParseError error;
    180     IDBParseKeyPath(keyPath.string(), keyPathElements, error);
    181     ASSERT(error == IDBKeyPathParseErrorNone);
    182 
    183205    if (!keyPathElements.size())
    184206        return 0;
Note: See TracChangeset for help on using the changeset viewer.