| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <title>IndexedDB: index renaming support</title> | |
| 3 <link rel="help" | |
| 4 href="https://w3c.github.io/IndexedDB/#dom-idbindex-name"> | |
| 5 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> | |
| 6 <script src="/resources/testharness.js"></script> | |
| 7 <script src="/resources/testharnessreport.js"></script> | |
| 8 <script src="support-promises.js"></script> | |
| 9 <script> | |
| 10 | |
| 11 promise_test(testCase => { | |
| 12 let authorIndex = null, authorIndex2 = null; | |
| 13 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; | |
| 14 return createDatabase(testCase, (database, transaction) => { | |
| 15 const store = createBooksStore(testCase, database); | |
| 16 authorIndex = store.index('by_author'); | |
| 17 }).then(database => { | |
| 18 const transaction = database.transaction('books', 'readonly'); | |
| 19 const store = transaction.objectStore('books'); | |
| 20 assert_array_equals( | |
| 21 store.indexNames, ['by_author', 'by_title'], | |
| 22 'Test setup should have created two indexes'); | |
| 23 authorIndex2 = store.index('by_author'); | |
| 24 return checkAuthorIndexContents( | |
| 25 testCase, authorIndex2, | |
| 26 'The index should have the expected contents before any renaming'). | |
| 27 then(() => database.close()); | |
| 28 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 29 const store = transaction.objectStore('books'); | |
| 30 renamedAuthorIndex = store.index('by_author'); | |
| 31 renamedAuthorIndex.name = 'renamed_by_author'; | |
| 32 | |
| 33 assert_equals( | |
| 34 renamedAuthorIndex.name, 'renamed_by_author', | |
| 35 'IDBIndex name should change immediately after a rename'); | |
| 36 assert_array_equals( | |
| 37 store.indexNames, ['by_title', 'renamed_by_author'], | |
| 38 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
| 39 assert_equals( | |
| 40 store.index('renamed_by_author'), renamedAuthorIndex, | |
| 41 'IDBObjectStore.index should return the renamed index store when ' + | |
| 42 'queried using the new name immediately after the rename'); | |
| 43 assert_throws( | |
| 44 'NotFoundError', () => store.index('by_author'), | |
| 45 'IDBObjectStore.index should throw when queried using the ' + | |
| 46 "renamed index's old name immediately after the rename"); | |
| 47 })).then(database => { | |
| 48 const transaction = database.transaction('books', 'readonly'); | |
| 49 const store = transaction.objectStore('books'); | |
| 50 assert_array_equals( | |
| 51 store.indexNames, ['by_title', 'renamed_by_author'], | |
| 52 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
| 53 'the versionchange transaction commits'); | |
| 54 renamedAuthorIndex2 = store.index('renamed_by_author'); | |
| 55 return checkAuthorIndexContents( | |
| 56 testCase, renamedAuthorIndex2, | |
| 57 'Renaming an index should not change its contents').then( | |
| 58 () => database.close()); | |
| 59 }).then(() => { | |
| 60 assert_equals( | |
| 61 authorIndex.name, 'by_author', | |
| 62 'IDBIndex obtained before the rename transaction should not ' + | |
| 63 'reflect the rename'); | |
| 64 assert_equals( | |
| 65 authorIndex2.name, 'by_author', | |
| 66 'IDBIndex obtained before the rename transaction should not ' + | |
| 67 'reflect the rename'); | |
| 68 assert_equals( | |
| 69 renamedAuthorIndex.name, 'renamed_by_author', | |
| 70 'IDBIndex used in the rename transaction should keep reflecting ' + | |
| 71 'the new name after the transaction is committed'); | |
| 72 assert_equals( | |
| 73 renamedAuthorIndex2.name, 'renamed_by_author', | |
| 74 'IDBIndex obtained after the rename transaction should reflect ' + | |
| 75 'the new name'); | |
| 76 }); | |
| 77 }, 'IndexedDB index rename in new transaction'); | |
| 78 | |
| 79 promise_test(testCase => { | |
| 80 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; | |
| 81 return createDatabase(testCase, (database, transaction) => { | |
| 82 const store = createBooksStore(testCase, database); | |
| 83 renamedAuthorIndex = store.index('by_author'); | |
| 84 renamedAuthorIndex.name = 'renamed_by_author'; | |
| 85 | |
| 86 assert_equals( | |
| 87 renamedAuthorIndex.name, 'renamed_by_author', | |
| 88 'IDBIndex name should change immediately after a rename'); | |
| 89 assert_array_equals( | |
| 90 store.indexNames, ['by_title', 'renamed_by_author'], | |
| 91 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
| 92 assert_equals( | |
| 93 store.index('renamed_by_author'), renamedAuthorIndex, | |
| 94 'IDBObjectStore.index should return the renamed index store when ' + | |
| 95 'queried using the new name immediately after the rename'); | |
| 96 assert_throws( | |
| 97 'NotFoundError', () => store.index('by_author'), | |
| 98 'IDBObjectStore.index should throw when queried using the ' + | |
| 99 "renamed index's old name immediately after the rename"); | |
| 100 }).then(database => { | |
| 101 const transaction = database.transaction('books', 'readonly'); | |
| 102 const store = transaction.objectStore('books'); | |
| 103 assert_array_equals( | |
| 104 store.indexNames, ['by_title', 'renamed_by_author'], | |
| 105 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
| 106 'the versionchange transaction commits'); | |
| 107 renamedAuthorIndex2 = store.index('renamed_by_author'); | |
| 108 return checkAuthorIndexContents( | |
| 109 testCase, renamedAuthorIndex2, | |
| 110 'Renaming an index should not change its contents').then( | |
| 111 () => database.close()); | |
| 112 }).then(() => { | |
| 113 assert_equals( | |
| 114 renamedAuthorIndex.name, 'renamed_by_author', | |
| 115 'IDBIndex used in the rename transaction should keep reflecting ' + | |
| 116 'the new name after the transaction is committed'); | |
| 117 assert_equals( | |
| 118 renamedAuthorIndex2.name, 'renamed_by_author', | |
| 119 'IDBIndex obtained after the rename transaction should reflect ' + | |
| 120 'the new name'); | |
| 121 }); | |
| 122 }, 'IndexedDB index rename in the transaction where it is created'); | |
| 123 | |
| 124 promise_test(testCase => { | |
| 125 return createDatabase(testCase, (database, transaction) => { | |
| 126 createBooksStore(testCase, database); | |
| 127 }).then(database => { | |
| 128 database.close(); | |
| 129 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 130 const store = transaction.objectStore('books'); | |
| 131 const index = store.index('by_author'); | |
| 132 index.name = 'by_author'; | |
| 133 assert_array_equals( | |
| 134 store.indexNames, ['by_author', 'by_title'], | |
| 135 'Renaming an index to the same name should not change the ' + | |
| 136 "index's IDBObjectStore.indexNames"); | |
| 137 })).then(database => { | |
| 138 const transaction = database.transaction('books', 'readonly'); | |
| 139 const store = transaction.objectStore('books'); | |
| 140 assert_array_equals( | |
| 141 store.indexNames, ['by_author', 'by_title'], | |
| 142 'Committing a transaction that renames a store to the same name ' + | |
| 143 "should not change the index's IDBObjectStore.indexNames"); | |
| 144 const index = store.index('by_author'); | |
| 145 return checkAuthorIndexContents( | |
| 146 testCase, index, | |
| 147 'Committing a transaction that renames an index to the same name ' + | |
| 148 "should not change the index's contents").then( | |
| 149 () => database.close()); | |
| 150 }); | |
| 151 }, 'IndexedDB index rename to the same name succeeds'); | |
| 152 | |
| 153 promise_test(testCase => { | |
| 154 return createDatabase(testCase, (database, transaction) => { | |
| 155 createBooksStore(testCase, database); | |
| 156 }).then(database => { | |
| 157 database.close(); | |
| 158 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 159 const store = transaction.objectStore('books'); | |
| 160 const index = store.index('by_author'); | |
| 161 store.deleteIndex('by_title'); | |
| 162 index.name = 'by_title'; | |
| 163 assert_array_equals( | |
| 164 store.indexNames, ['by_title'], | |
| 165 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
| 166 })).then(database => { | |
| 167 const transaction = database.transaction('books', 'readonly'); | |
| 168 const store = transaction.objectStore('books'); | |
| 169 assert_array_equals( | |
| 170 store.indexNames, ['by_title'], | |
| 171 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
| 172 'the versionchange transaction commits'); | |
| 173 const index = store.index('by_title'); | |
| 174 return checkAuthorIndexContents( | |
| 175 testCase, index, | |
| 176 'Renaming an index should not change its contents').then( | |
| 177 () => database.close()); | |
| 178 }); | |
| 179 }, 'IndexedDB index rename to the name of a deleted index succeeds'); | |
| 180 | |
| 181 promise_test(testCase => { | |
| 182 return createDatabase(testCase, (database, transaction) => { | |
| 183 createBooksStore(testCase, database); | |
| 184 }).then(database => { | |
| 185 database.close(); | |
| 186 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 187 const store = transaction.objectStore('books'); | |
| 188 store.index('by_author').name = 'tmp'; | |
| 189 store.index('by_title').name = 'by_author'; | |
| 190 store.index('tmp').name = 'by_title'; | |
| 191 assert_array_equals( | |
| 192 store.indexNames, ['by_author', 'by_title'], | |
| 193 'IDBObjectStore.indexNames should reflect the swap immediately ' + | |
| 194 'after the renames'); | |
| 195 return checkTitleIndexContents( | |
| 196 testCase, store.index('by_author'), | |
| 197 'Renaming an index should not change its contents'); | |
| 198 })).then(database => { | |
| 199 const transaction = database.transaction('books', 'readonly'); | |
| 200 const store = transaction.objectStore('books'); | |
| 201 assert_array_equals( | |
| 202 store.indexNames, ['by_author', 'by_title'], | |
| 203 'IDBObjectStore.indexNames should still reflect the swap after ' + | |
| 204 'the versionchange transaction commits'); | |
| 205 const index = store.index('by_title'); | |
| 206 return checkAuthorIndexContents( | |
| 207 testCase, index, | |
| 208 'Renaming an index should not change its contents').then( | |
| 209 () => database.close()); | |
| 210 }); | |
| 211 }, 'IndexedDB index swapping via renames succeeds'); | |
| 212 | |
| 213 promise_test(testCase => { | |
| 214 return createDatabase(testCase, (database, transaction) => { | |
| 215 createBooksStore(testCase, database); | |
| 216 }).then(database => { | |
| 217 database.close(); | |
| 218 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 219 const store = transaction.objectStore('books'); | |
| 220 const index = store.index('by_author'); | |
| 221 | |
| 222 index.name = 42; | |
| 223 assert_equals(index.name, '42', | |
| 224 'IDBIndex name should change immediately after a rename to a ' + | |
| 225 'number'); | |
| 226 assert_array_equals( | |
| 227 store.indexNames, ['42', 'by_title'], | |
| 228 'IDBObjectStore.indexNames should immediately reflect the ' + | |
| 229 'stringifying rename'); | |
| 230 | |
| 231 index.name = true; | |
| 232 assert_equals(index.name, 'true', | |
| 233 'IDBIndex name should change immediately after a rename to a ' + | |
| 234 'boolean'); | |
| 235 | |
| 236 index.name = {}; | |
| 237 assert_equals(index.name, '[object Object]', | |
| 238 'IDBIndex name should change immediately after a rename to an ' + | |
| 239 'object'); | |
| 240 | |
| 241 index.name = () => null; | |
| 242 assert_equals(index.name, '() => null', | |
| 243 'IDBIndex name should change immediately after a rename to a ' + | |
| 244 'function'); | |
| 245 | |
| 246 index.name = undefined; | |
| 247 assert_equals(index.name, 'undefined', | |
| 248 'IDBIndex name should change immediately after a rename to ' + | |
| 249 'undefined'); | |
| 250 })).then(database => { | |
| 251 const transaction = database.transaction('books', 'readonly'); | |
| 252 const store = transaction.objectStore('books'); | |
| 253 assert_array_equals( | |
| 254 store.indexNames, ['by_title', 'undefined'], | |
| 255 'IDBObjectStore.indexNames should reflect the last rename ' + | |
| 256 'after the versionchange transaction commits'); | |
| 257 const index = store.index('undefined'); | |
| 258 return checkAuthorIndexContents( | |
| 259 testCase, index, | |
| 260 'Renaming an index should not change its contents').then( | |
| 261 () => database.close()); | |
| 262 }); | |
| 263 }, 'IndexedDB index rename stringifies non-string names'); | |
| 264 | |
| 265 for (let escapedName of ['', '\\u0000', '\\uDC00\\uD800']) ((escapedName) => { | |
| 266 const name = JSON.parse('"' + escapedName + '"'); | |
| 267 promise_test(testCase => { | |
| 268 return createDatabase(testCase, (database, transaction) => { | |
| 269 createBooksStore(testCase, database); | |
| 270 }).then(database => { | |
| 271 database.close(); | |
| 272 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
| 273 const store = transaction.objectStore('books'); | |
| 274 const index = store.index('by_author'); | |
| 275 | |
| 276 index.name = name; | |
| 277 assert_equals(index.name, name, | |
| 278 'IDBIndex name should change immediately after the rename'); | |
| 279 assert_array_equals( | |
| 280 store.indexNames, [name, 'by_title'].sort(), | |
| 281 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
| 282 })).then(database => { | |
| 283 const transaction = database.transaction('books', 'readonly'); | |
| 284 const store = transaction.objectStore('books'); | |
| 285 assert_array_equals( | |
| 286 store.indexNames, [name, 'by_title'].sort(), | |
| 287 'IDBObjectStore.indexNames should reflect the rename ' + | |
| 288 'after the versionchange transaction commits'); | |
| 289 const index = store.index(name); | |
| 290 return checkAuthorIndexContents( | |
| 291 testCase, index, | |
| 292 'Renaming an index should not change its contents').then( | |
| 293 () => database.close()); | |
| 294 }); | |
| 295 }, 'IndexedDB index can be renamed to "' + escapedName + '"'); | |
| 296 })(escapedName); | |
| 297 | |
| 298 </script> | |
| OLD | NEW |