idbcursor_update_index.any.js (8832B)
1 // META: global=window,worker 2 // META: title=IDBCursor.update() - 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 const records = [ 26 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 27 { pKey: "primaryKey_1", iKey: "indexKey_1" } 28 ]; 29 30 let open_rq = createdb(t); 31 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 32 33 open_rq.onsuccess = CursorUpdateRecord; 34 35 36 function CursorUpdateRecord(e) { 37 let txn = dbObj.db.transaction("test", "readwrite"), cursor_rq = txn.objectStore("test") 38 .index("index") 39 .openCursor(); 40 cursor_rq.onsuccess = t.step_func(function (e) { 41 let cursor = e.target.result; 42 43 cursor.value.iKey += "_updated"; 44 cursor.update(cursor.value); 45 }); 46 47 txn.oncomplete = t.step_func(VerifyRecordWasUpdated); 48 } 49 50 51 function VerifyRecordWasUpdated(e) { 52 let cursor_rq = dbObj.db.transaction("test", "readonly") 53 .objectStore("test") 54 .openCursor(); 55 56 cursor_rq.onsuccess = t.step_func(function (e) { 57 let cursor = e.target.result; 58 assert_equals(cursor.value.iKey, records[0].iKey + "_updated"); 59 60 t.done(); 61 }); 62 } 63 64 }, "Modify a record in the object store "); 65 66 async_test(t => { 67 let dbObj = {}; 68 const records = [ 69 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 70 { pKey: "primaryKey_1", iKey: "indexKey_1" } 71 ]; 72 73 let open_rq = createdb(t); 74 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 75 76 open_rq.onsuccess = function (e) { 77 let cursor_rq = dbObj.db.transaction("test", "readonly") 78 .objectStore("test") 79 .index("index") 80 .openCursor(); 81 82 cursor_rq.onsuccess = t.step_func(function (e) { 83 let cursor = e.target.result; 84 assert_throws_dom('ReadOnlyError', 85 function () { cursor.update(cursor.value); }); 86 87 t.done(); 88 }); 89 } 90 91 }, "Attempt to modify a record in a read-only transaction"); 92 93 async_test(t => { 94 let db; 95 const records = [ 96 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 97 { pKey: "primaryKey_1", iKey: "indexKey_1" } 98 ]; 99 100 let open_rq = createdb(t); 101 open_rq.onupgradeneeded = function (e) { 102 db = e.target.result; 103 let objStore = db.createObjectStore("test", { keyPath: "pKey" }); 104 let index = objStore.createIndex("index", "iKey"); 105 106 for (let i = 0; i < records.length; i++) 107 objStore.add(records[i]); 108 109 let cursor_rq = index.openCursor(); 110 111 cursor_rq.onsuccess = t.step_func(function (e) { 112 let cursor = e.target.result; 113 assert_true(cursor instanceof IDBCursor, "cursor exist"); 114 self.cursor = cursor; 115 self.record = cursor.value; 116 }); 117 118 e.target.transaction.oncomplete = t.step_func(function (e) { 119 assert_throws_dom('TransactionInactiveError', 120 function () { self.cursor.update(self.record); }) 121 122 t.done(); 123 }); 124 } 125 126 }, "Attempt to modify a record in an inactive transaction"); 127 128 async_test(t => { 129 let db; 130 const records = [ 131 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 132 { pKey: "primaryKey_1", iKey: "indexKey_1" } 133 ]; 134 135 let open_rq = createdb(t); 136 open_rq.onupgradeneeded = function (event) { 137 db = event.target.result; 138 let objStore = createObjectStoreWithIndexAndPopulate(db, records); 139 let rq = objStore.index("index").openCursor(); 140 141 rq.onsuccess = t.step_func(function (event) { 142 let cursor = event.target.result; 143 assert_true(cursor instanceof IDBCursor); 144 145 db.deleteObjectStore("test"); 146 cursor.value.iKey += "_updated"; 147 assert_throws_dom("InvalidStateError", 148 function () { cursor.update(cursor.value); }); 149 150 t.done(); 151 }); 152 } 153 154 }, "Attempt to modify a record after the cursor's source or effective object store has been deleted. The implementation MUST throw a DOMException of type InvalidStateError"); 155 156 async_test(t => { 157 let dbObj = {}; 158 const records = [ 159 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 160 { pKey: "primaryKey_1", iKey: "indexKey_1" } 161 ]; 162 163 let open_rq = createdb(t); 164 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 165 166 open_rq.onsuccess = function (e) { 167 let cursor_rq = dbObj.db.transaction("test", "readwrite") 168 .objectStore("test") 169 .index("index") 170 .openCursor(); 171 172 cursor_rq.onsuccess = t.step_func(function (e) { 173 let cursor = e.target.result; 174 assert_true(cursor instanceof IDBCursor); 175 176 let record = cursor.value; 177 record.data = self; 178 assert_throws_dom('DataCloneError', 179 function () { cursor.update(record); }); 180 181 t.done(); 182 }); 183 } 184 }, "Throw DataCloneError"); 185 186 async_test(t => { 187 let dbObj = {}; 188 const records = [ 189 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 190 { pKey: "primaryKey_1", iKey: "indexKey_1" } 191 ]; 192 193 let open_rq = createdb(t); 194 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 195 196 open_rq.onsuccess = function (e) { 197 let cursor_rq = dbObj.db.transaction("test", "readonly") 198 .objectStore("test") 199 .index("index") 200 .openCursor(); 201 202 cursor_rq.onsuccess = t.step_func(function (e) { 203 let cursor = e.target.result; 204 assert_true(cursor instanceof IDBCursor); 205 assert_throws_js(TypeError, function () { cursor.update(); }); 206 207 t.done(); 208 }); 209 } 210 }, "No argument"); 211 212 async_test(t => { 213 let dbObj = {}; 214 const records = [ 215 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 216 { pKey: "primaryKey_1", iKey: "indexKey_1" } 217 ]; 218 219 let open_rq = createdb(t); 220 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 221 open_rq.onsuccess = function (e) { 222 let cursor_rq = dbObj.db.transaction("test", "readwrite") 223 .objectStore("test") 224 .index("index") 225 .openCursor(); 226 227 cursor_rq.onsuccess = t.step_func(function (e) { 228 let cursor = e.target.result; 229 assert_true(cursor instanceof IDBCursor); 230 assert_throws_dom('DataError', function () { cursor.update(null); }); 231 232 t.done(); 233 }); 234 } 235 }, "Throw DataError"); 236 237 async_test(t => { 238 let dbObj = {}; 239 const records = [ 240 { pKey: "primaryKey_0", iKey: "indexKey_0" }, 241 { pKey: "primaryKey_1", iKey: "indexKey_1" } 242 ]; 243 244 let open_rq = createdb(t); 245 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 246 open_rq.onsuccess = function (e) { 247 let cursor_rq = dbObj.db.transaction("test", "readwrite") 248 .objectStore("test") 249 .index("index") 250 .openCursor(); 251 252 cursor_rq.onsuccess = t.step_func(function (e) { 253 let cursor = e.target.result; 254 assert_true(cursor instanceof IDBCursor, "cursor exists"); 255 256 cursor.continue(); 257 assert_throws_dom("InvalidStateError", function () { 258 cursor.update({ pKey: "primaryKey_0", iKey: "indexKey_0_updated" }); 259 }); 260 261 t.done(); 262 }); 263 } 264 }, "Throw InvalidStateError when the cursor is being iterated"); 265 266 async_test(t => { 267 let dbObj = {}; 268 const records = [ 269 { pKey: "primaryKey_1", iKey: 1 }, 270 { pKey: "primaryKey_2", iKey: 2 }, 271 { pKey: "primaryKey_3", iKey: 3 }, 272 ]; 273 274 let open_rq = createdb(t); 275 open_rq.onupgradeneeded = setOnUpgradeNeeded(dbObj, records); 276 277 open_rq.onsuccess = t.step_func(ModifyRecordsInIteration); 278 279 // Iterate and modify values during iteration 280 function ModifyRecordsInIteration(e) { 281 let txn = dbObj.db.transaction("test", "readwrite"); 282 let index = txn.objectStore("test").index("index"); 283 let cursor_rq = index.openCursor(IDBKeyRange.upperBound(9)); 284 285 cursor_rq.onsuccess = t.step_func(function (e) { 286 let cursor = e.target.result; 287 288 if (!cursor) { 289 return; 290 } 291 292 // Modify the record's value during iteration 293 let record = cursor.value; 294 record.iKey += 1; 295 cursor.update(record); 296 297 cursor.continue(); 298 }); 299 300 txn.oncomplete = t.step_func(VerifyUpdatedRecords); 301 } 302 303 // Verify that the records were updated correctly 304 function VerifyUpdatedRecords(e) { 305 let txn = dbObj.db.transaction("test", "readonly"); 306 let objectStore = txn.objectStore("test"); 307 let getAll_rq = objectStore.getAll(); 308 309 getAll_rq.onsuccess = t.step_func(function (e) { 310 // All values should have been incremented to 10 311 assert_array_equals( 312 e.target.result.map(record => record.iKey), 313 [10, 10, 10], 314 'iKey values should all be incremented until bound reached'); 315 316 t.done(); 317 }); 318 } 319 320 }, "Modify records during cursor iteration and verify updated records");