idbcursor_continue_index.any.js (11801B)
1 // META: global=window,worker 2 // META: title=IDBCursor.continue() - index 3 // META: script=resources/support.js 4 5 'use strict'; 6 7 function createObjectStoreWithIndexAndPopulate(db, records) { 8 let objStore = db.createObjectStore("test", { keyPath: "pKey" }); 9 objStore.createIndex("index", "iKey"); 10 for (let i = 0; i < records.length; i++) { 11 objStore.add(records[i]); 12 } 13 return objStore; 14 } 15 16 function setOnUpgradeNeeded(dbObj, records) { 17 return function (event) { 18 dbObj.db = event.target.result; 19 createObjectStoreWithIndexAndPopulate(dbObj.db, records); 20 }; 21 } 22 23 async_test(t => { 24 let dbObj = {}; 25 let count = 0; 26 const records = [ 27 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 28 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 29 { pKey: "primaryKey_1-2", iKey: "indexKey_1" } 30 ]; 31 32 let open_rq = createdb(t); 33 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 34 35 open_rq.onsuccess = function (e) { 36 let cursor_rq = dbObj.db.transaction("test", "readonly") 37 .objectStore("test") 38 .index("index") 39 .openCursor(); 40 41 cursor_rq.onsuccess = t.step_func(function (e) { 42 let cursor = e.target.result; 43 if (!cursor) { 44 assert_equals(count, records.length, "cursor run count"); 45 t.done(); 46 } 47 48 let record = cursor.value; 49 assert_equals(record.pKey, records[count].pKey, "primary key"); 50 assert_equals(record.iKey, records[count].iKey, "index key"); 51 52 cursor.continue(); 53 count++; 54 }); 55 }; 56 }, "Iterate to the next record"); 57 58 async_test(t => { 59 let dbObj = {}; 60 const records = [ 61 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 62 { pKey: "primaryKey_1", iKey: "indexKey_1" } 63 ]; 64 65 let open_rq = createdb(t); 66 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 67 68 open_rq.onsuccess = function (e) { 69 let cursor_rq = dbObj.db.transaction("test", "readonly") 70 .objectStore("test") 71 .index("index") 72 .openCursor(); 73 74 cursor_rq.onsuccess = t.step_func(function (e) { 75 let cursor = e.target.result; 76 77 assert_throws_dom("DataError", 78 function () { cursor.continue(-1); }); 79 80 assert_true(cursor instanceof IDBCursorWithValue, "cursor"); 81 82 t.done(); 83 }); 84 }; 85 }, "Attempt to pass a key parameter that is not a valid key"); 86 87 async_test(t => { 88 let dbObj = {}; 89 let count = 0; 90 const records = [ 91 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 92 { pKey: "primaryKey_1", iKey: "indexKey_1" } 93 ]; 94 95 let open_rq = createdb(t); 96 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 97 98 open_rq.onsuccess = function (e) { 99 let cursor_rq = dbObj.db.transaction("test", "readonly") 100 .objectStore("test") 101 .index("index") 102 .openCursor(undefined, "next"); // XXX: Fx has issue with "undefined" 103 104 cursor_rq.onsuccess = t.step_func(function (e) { 105 let cursor = e.target.result; 106 if (!cursor) { 107 assert_equals(count, 2, "ran number of times"); 108 t.done(); 109 } 110 111 // First time checks key equal, second time checks key less than 112 assert_throws_dom("DataError", 113 function () { cursor.continue(records[0].iKey); }); 114 115 cursor.continue(); 116 117 count++; 118 }); 119 }; 120 }, "Attempt to iterate to the previous record when the direction is set for the next record"); 121 122 async_test(t => { 123 let dbObj = {}; 124 let count = 0; 125 const records = [ 126 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 127 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 128 { pKey: "primaryKey_2", iKey: "indexKey_2" } 129 ]; 130 131 let open_rq = createdb(t); 132 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 133 134 open_rq.onsuccess = function (e) { 135 let cursor_rq = dbObj.db.transaction("test", "readonly") 136 .objectStore("test") 137 .index("index") 138 .openCursor(undefined, "prev"); // XXX Fx issues w undefined 139 140 cursor_rq.onsuccess = t.step_func(function (e) { 141 let cursor = e.target.result; 142 let record = cursor.value; 143 144 switch (count) { 145 case 0: 146 assert_equals(record.pKey, records[2].pKey, "first pKey"); 147 assert_equals(record.iKey, records[2].iKey, "first iKey"); 148 cursor.continue(); 149 break; 150 151 case 1: 152 assert_equals(record.pKey, records[1].pKey, "second pKey"); 153 assert_equals(record.iKey, records[1].iKey, "second iKey"); 154 assert_throws_dom("DataError", 155 function () { cursor.continue("indexKey_2"); }); 156 t.done(); 157 break; 158 159 default: 160 assert_unreached("Unexpected count value: " + count); 161 } 162 163 count++; 164 }); 165 }; 166 }, "Attempt to iterate to the next record when the direction is set for the previous record"); 167 168 async_test(t => { 169 let dbObj = {}; 170 let count = 0; 171 const records = [ 172 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 173 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 174 { pKey: "primaryKey_1-2", iKey: "indexKey_1" }, 175 { pKey: "primaryKey_2", iKey: "indexKey_2" } 176 ]; 177 178 let open_rq = createdb(t); 179 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 180 181 open_rq.onsuccess = function (e) { 182 let cursor_rq = dbObj.db.transaction("test", "readonly") 183 .objectStore("test") 184 .index("index") 185 .openCursor(undefined, "prevunique"); 186 187 const expected = [ 188 { pKey: "primaryKey_2", iKey: "indexKey_2" }, 189 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 190 { pKey: "primaryKey_0", iKey: "indexKey_0" } 191 ]; 192 193 cursor_rq.onsuccess = t.step_func(function (e) { 194 if (!e.target.result) { 195 assert_equals(count, expected.length, 'count'); 196 t.done(); 197 return; 198 } 199 let cursor = e.target.result; 200 let record = cursor.value; 201 202 assert_equals(record.pKey, expected[count].pKey, "pKey #" + count); 203 assert_equals(record.iKey, expected[count].iKey, "iKey #" + count); 204 205 assert_equals(cursor.key, expected[count].iKey, "cursor.key #" + count); 206 assert_equals(cursor.primaryKey, expected[count].pKey, "cursor.primaryKey #" + count); 207 208 count++; 209 cursor.continue(expected[count] ? expected[count].iKey : undefined); 210 }); 211 }; 212 }, "Iterate using 'prevunique'"); 213 214 async_test(t => { 215 let dbObj = {}; 216 let count = 0; 217 const records = [ 218 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 219 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 220 { pKey: "primaryKey_1-2", iKey: "indexKey_1" }, 221 { pKey: "primaryKey_2", iKey: "indexKey_2" } 222 ]; 223 224 let open_rq = createdb(t); 225 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 226 227 open_rq.onsuccess = function (e) { 228 let cursor_rq = dbObj.db.transaction("test", "readonly") 229 .objectStore("test") 230 .index("index") 231 .openCursor(undefined, "nextunique"); 232 233 const expected = [ 234 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 235 { pKey: "primaryKey_1", iKey: "indexKey_1" }, 236 { pKey: "primaryKey_2", iKey: "indexKey_2" } 237 ]; 238 239 cursor_rq.onsuccess = t.step_func(function (e) { 240 if (!e.target.result) { 241 assert_equals(count, expected.length, 'count'); 242 t.done(); 243 return; 244 } 245 let cursor = e.target.result; 246 let record = cursor.value; 247 248 assert_equals(record.pKey, expected[count].pKey, "pKey #" + count); 249 assert_equals(record.iKey, expected[count].iKey, "iKey #" + count); 250 251 assert_equals(cursor.key, expected[count].iKey, "cursor.key #" + count); 252 assert_equals(cursor.primaryKey, expected[count].pKey, "cursor.primaryKey #" + count); 253 254 count++; 255 cursor.continue(expected[count] ? expected[count].iKey : undefined); 256 }); 257 }; 258 }, "Iterate using nextunique"); 259 260 async_test(t => { 261 let db; 262 const records = [ 263 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 264 { pKey: "primaryKey_1", iKey: "indexKey_1" } 265 ]; 266 267 let open_rq = createdb(t); 268 open_rq.onupgradeneeded = function (event) { 269 db = event.target.result; 270 let objStore = createObjectStoreWithIndexAndPopulate(db, records); 271 let rq = objStore.index("index").openCursor(); 272 rq.onsuccess = t.step_func(function (event) { 273 let cursor = event.target.result; 274 assert_true(cursor instanceof IDBCursor); 275 276 event.target.transaction.abort(); 277 assert_throws_dom("TransactionInactiveError", 278 function () { cursor.continue(); }); 279 280 t.done(); 281 }); 282 } 283 }, "Calling continue() should throw an exception TransactionInactiveError when the transaction is not active."); 284 285 async_test(t => { 286 let db; 287 const records = [ 288 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 289 { pKey: "primaryKey_1", iKey: "indexKey_1" } 290 ]; 291 292 let open_rq = createdb(t); 293 open_rq.onupgradeneeded = function (event) { 294 db = event.target.result; 295 let objStore = createObjectStoreWithIndexAndPopulate(db, records); 296 let rq = objStore.index("index").openCursor(); 297 rq.onsuccess = t.step_func(function (event) { 298 let cursor = event.target.result; 299 assert_true(cursor instanceof IDBCursor); 300 301 db.deleteObjectStore("test"); 302 assert_throws_dom("InvalidStateError", 303 function () { cursor.continue(); }); 304 305 t.done(); 306 }); 307 } 308 }, "If the cursor's source or effective object store has been deleted, the implementation MUST throw a DOMException of type InvalidStateError"); 309 310 async_test(t => { 311 let db; 312 let count = 0; 313 const records = [ 314 { pKey: "primaryKey_0", obj: { iKey: "iKey_0" } }, 315 { pKey: "primaryKey_1", obj: { iKey: "iKey_1" } }, 316 { pKey: "primaryKey_2", obj: { iKey: "iKey_2" } } 317 ]; 318 319 const expected = [ 320 ["primaryKey_2", "iKey_2"], 321 ["primaryKey_0", "iKey_0"] 322 ]; 323 324 let open_rq = createdb(t); 325 open_rq.onupgradeneeded = function (e) { 326 db = e.target.result; 327 var objStore = db.createObjectStore("test", { keyPath: ["pKey", "obj.iKey"] }); 328 objStore.createIndex("index", ["pKey", "obj.iKey"]); 329 330 for (var i = 0; i < records.length; i++) 331 objStore.add(records[i]); 332 }; 333 334 open_rq.onsuccess = function (e) { 335 var cursor_rq = db.transaction("test", "readwrite") 336 .objectStore("test") 337 .index("index") 338 .openCursor(null, "prev"); 339 340 cursor_rq.onsuccess = t.step_func(function (e) { 341 var cursor = e.target.result; 342 if (!cursor) { 343 assert_equals(count, 2, "cursor run count"); 344 t.done(); 345 } 346 347 if (count === 0) { 348 e.target.source.objectStore.delete(["primaryKey_1", "iKey_1"]); 349 } 350 assert_array_equals(cursor.key, expected[count], "primary key"); 351 352 cursor.continue(); 353 count++; 354 }); 355 } 356 }, "Delete next element, and iterate to it"); 357 358 async_test(t => { 359 let db; 360 let count = 0; 361 const records = [ 362 { pKey: "primaryKey_0", obj: { iKey: "iKey_0" } }, 363 { pKey: "primaryKey_2", obj: { iKey: "iKey_2" } } 364 ]; 365 366 const expected = [ 367 ["primaryKey_2", "iKey_2"], 368 ["primaryKey_1", "iKey_1"], 369 ["primaryKey_0", "iKey_0"] 370 ]; 371 372 let open_rq = createdb(t); 373 open_rq.onupgradeneeded = function (e) { 374 db = e.target.result; 375 var objStore = db.createObjectStore("test", { keyPath: "pKey" }); 376 objStore.createIndex("index", ["pKey", "obj.iKey"]); 377 378 for (var i = 0; i < records.length; i++) 379 objStore.add(records[i]); 380 }; 381 382 open_rq.onsuccess = function (e) { 383 var cursor_rq = db.transaction("test", "readwrite") 384 .objectStore("test") 385 .index("index") 386 .openCursor(null, "prev"); 387 388 cursor_rq.onsuccess = t.step_func(function (e) { 389 var cursor = e.target.result; 390 if (!cursor) { 391 assert_equals(count, 3, "cursor run count"); 392 t.done(); 393 } 394 395 if (count === 0) { 396 e.target.source.objectStore.add({ pKey: "primaryKey_1", obj: { iKey: "iKey_1" } }); 397 } 398 assert_array_equals(cursor.key, expected[count], "primary key"); 399 400 cursor.continue(); 401 count++; 402 }); 403 } 404 }, "Add next element, and iterate to it");