OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
13 * distribution. | 13 * distribution. |
14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | |
31 /** | 30 /** |
32 * @constructor | 31 * @unrestricted |
33 * @extends {WebInspector.SDKModel} | |
34 * @param {!WebInspector.Target} target | |
35 * @param {!WebInspector.SecurityOriginManager} securityOriginManager | |
36 */ | 32 */ |
37 WebInspector.IndexedDBModel = function(target, securityOriginManager) | 33 WebInspector.IndexedDBModel = class extends WebInspector.SDKModel { |
38 { | 34 /** |
39 WebInspector.SDKModel.call(this, WebInspector.IndexedDBModel, target); | 35 * @param {!WebInspector.Target} target |
| 36 * @param {!WebInspector.SecurityOriginManager} securityOriginManager |
| 37 */ |
| 38 constructor(target, securityOriginManager) { |
| 39 super(WebInspector.IndexedDBModel, target); |
40 this._securityOriginManager = securityOriginManager; | 40 this._securityOriginManager = securityOriginManager; |
41 this._agent = target.indexedDBAgent(); | 41 this._agent = target.indexedDBAgent(); |
42 | 42 |
43 /** @type {!Map.<!WebInspector.IndexedDBModel.DatabaseId, !WebInspector.Inde
xedDBModel.Database>} */ | 43 /** @type {!Map.<!WebInspector.IndexedDBModel.DatabaseId, !WebInspector.Inde
xedDBModel.Database>} */ |
44 this._databases = new Map(); | 44 this._databases = new Map(); |
45 /** @type {!Object.<string, !Array.<string>>} */ | 45 /** @type {!Object.<string, !Array.<string>>} */ |
46 this._databaseNamesBySecurityOrigin = {}; | 46 this._databaseNamesBySecurityOrigin = {}; |
47 }; | 47 } |
48 | 48 |
49 WebInspector.IndexedDBModel.KeyTypes = { | 49 /** |
50 NumberType: "number", | 50 * @param {*} idbKey |
51 StringType: "string", | 51 * @return {({ |
52 DateType: "date", | 52 * array: (!Array<?>|undefined), |
53 ArrayType: "array" | 53 * date: (number|undefined), |
54 }; | 54 * number: (number|undefined), |
55 | 55 * string: (string|undefined), |
56 WebInspector.IndexedDBModel.KeyPathTypes = { | 56 * type: !IndexedDBAgent.KeyType<string> |
57 NullType: "null", | 57 * }|undefined)} |
58 StringType: "string", | 58 */ |
59 ArrayType: "array" | 59 static keyFromIDBKey(idbKey) { |
60 }; | 60 if (typeof(idbKey) === 'undefined' || idbKey === null) |
61 | 61 return undefined; |
62 /** | |
63 * @param {*} idbKey | |
64 * @return {({ | |
65 * array: (!Array<?>|undefined), | |
66 * date: (number|undefined), | |
67 * number: (number|undefined), | |
68 * string: (string|undefined), | |
69 * type: !IndexedDBAgent.KeyType<string> | |
70 * }|undefined)} | |
71 */ | |
72 WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey) | |
73 { | |
74 if (typeof(idbKey) === "undefined" || idbKey === null) | |
75 return undefined; | |
76 | 62 |
77 var type; | 63 var type; |
78 var key = {}; | 64 var key = {}; |
79 switch (typeof(idbKey)) { | 65 switch (typeof(idbKey)) { |
80 case "number": | 66 case 'number': |
81 key.number = idbKey; | 67 key.number = idbKey; |
82 type = WebInspector.IndexedDBModel.KeyTypes.NumberType; | 68 type = WebInspector.IndexedDBModel.KeyTypes.NumberType; |
83 break; | 69 break; |
84 case "string": | 70 case 'string': |
85 key.string = idbKey; | 71 key.string = idbKey; |
86 type = WebInspector.IndexedDBModel.KeyTypes.StringType; | 72 type = WebInspector.IndexedDBModel.KeyTypes.StringType; |
87 break; | 73 break; |
88 case "object": | 74 case 'object': |
89 if (idbKey instanceof Date) { | 75 if (idbKey instanceof Date) { |
90 key.date = idbKey.getTime(); | 76 key.date = idbKey.getTime(); |
91 type = WebInspector.IndexedDBModel.KeyTypes.DateType; | 77 type = WebInspector.IndexedDBModel.KeyTypes.DateType; |
92 } else if (Array.isArray(idbKey)) { | 78 } else if (Array.isArray(idbKey)) { |
93 key.array = []; | 79 key.array = []; |
94 for (var i = 0; i < idbKey.length; ++i) | 80 for (var i = 0; i < idbKey.length; ++i) |
95 key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[
i])); | 81 key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]))
; |
96 type = WebInspector.IndexedDBModel.KeyTypes.ArrayType; | 82 type = WebInspector.IndexedDBModel.KeyTypes.ArrayType; |
97 } | 83 } |
98 break; | 84 break; |
99 default: | 85 default: |
100 return undefined; | 86 return undefined; |
101 } | 87 } |
102 key.type = /** @type {!IndexedDBAgent.KeyType<string>} */ (type); | 88 key.type = /** @type {!IndexedDBAgent.KeyType<string>} */ (type); |
103 return key; | 89 return key; |
104 }; | 90 } |
105 | 91 |
106 /** | 92 /** |
107 * @param {?IDBKeyRange=} idbKeyRange | 93 * @param {?IDBKeyRange=} idbKeyRange |
108 * @return {?IndexedDBAgent.KeyRange} | 94 * @return {?IndexedDBAgent.KeyRange} |
109 * eturn {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}} | 95 * eturn {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}} |
110 */ | 96 */ |
111 WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange) | 97 static keyRangeFromIDBKeyRange(idbKeyRange) { |
112 { | 98 if (typeof idbKeyRange === 'undefined' || idbKeyRange === null) |
113 if (typeof idbKeyRange === "undefined" || idbKeyRange === null) | 99 return null; |
114 return null; | |
115 | 100 |
116 var keyRange = {}; | 101 var keyRange = {}; |
117 keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower
); | 102 keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower
); |
118 keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper
); | 103 keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper
); |
119 keyRange.lowerOpen = !!idbKeyRange.lowerOpen; | 104 keyRange.lowerOpen = !!idbKeyRange.lowerOpen; |
120 keyRange.upperOpen = !!idbKeyRange.upperOpen; | 105 keyRange.upperOpen = !!idbKeyRange.upperOpen; |
121 return keyRange; | 106 return keyRange; |
122 }; | 107 } |
123 | 108 |
124 /** | 109 /** |
125 * @param {!IndexedDBAgent.KeyPath} keyPath | 110 * @param {!IndexedDBAgent.KeyPath} keyPath |
126 * @return {?string|!Array.<string>|undefined} | 111 * @return {?string|!Array.<string>|undefined} |
127 */ | 112 */ |
128 WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath) | 113 static idbKeyPathFromKeyPath(keyPath) { |
129 { | |
130 var idbKeyPath; | 114 var idbKeyPath; |
131 switch (keyPath.type) { | 115 switch (keyPath.type) { |
132 case WebInspector.IndexedDBModel.KeyPathTypes.NullType: | 116 case WebInspector.IndexedDBModel.KeyPathTypes.NullType: |
133 idbKeyPath = null; | 117 idbKeyPath = null; |
134 break; | 118 break; |
135 case WebInspector.IndexedDBModel.KeyPathTypes.StringType: | 119 case WebInspector.IndexedDBModel.KeyPathTypes.StringType: |
136 idbKeyPath = keyPath.string; | 120 idbKeyPath = keyPath.string; |
137 break; | 121 break; |
138 case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType: | 122 case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType: |
139 idbKeyPath = keyPath.array; | 123 idbKeyPath = keyPath.array; |
140 break; | 124 break; |
141 } | 125 } |
142 return idbKeyPath; | 126 return idbKeyPath; |
143 }; | 127 } |
144 | 128 |
145 /** | 129 /** |
146 * @param {?string|!Array.<string>|undefined} idbKeyPath | 130 * @param {?string|!Array.<string>|undefined} idbKeyPath |
147 * @return {?string} | 131 * @return {?string} |
148 */ | 132 */ |
149 WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath) | 133 static keyPathStringFromIDBKeyPath(idbKeyPath) { |
150 { | 134 if (typeof idbKeyPath === 'string') |
151 if (typeof idbKeyPath === "string") | 135 return '"' + idbKeyPath + '"'; |
152 return "\"" + idbKeyPath + "\""; | |
153 if (idbKeyPath instanceof Array) | 136 if (idbKeyPath instanceof Array) |
154 return "[\"" + idbKeyPath.join("\", \"") + "\"]"; | 137 return '["' + idbKeyPath.join('", "') + '"]'; |
155 return null; | 138 return null; |
156 }; | 139 } |
| 140 |
| 141 /** |
| 142 * @param {!WebInspector.Target} target |
| 143 * @return {!WebInspector.IndexedDBModel} |
| 144 */ |
| 145 static fromTarget(target) { |
| 146 var model = /** @type {?WebInspector.IndexedDBModel} */ (target.model(WebIns
pector.IndexedDBModel)); |
| 147 if (!model) |
| 148 model = new WebInspector.IndexedDBModel(target, WebInspector.SecurityOrigi
nManager.fromTarget(target)); |
| 149 return model; |
| 150 } |
| 151 |
| 152 enable() { |
| 153 if (this._enabled) |
| 154 return; |
| 155 |
| 156 this._agent.enable(); |
| 157 this._securityOriginManager.addEventListener( |
| 158 WebInspector.SecurityOriginManager.Events.SecurityOriginAdded, this._sec
urityOriginAdded, this); |
| 159 this._securityOriginManager.addEventListener( |
| 160 WebInspector.SecurityOriginManager.Events.SecurityOriginRemoved, this._s
ecurityOriginRemoved, this); |
| 161 |
| 162 for (var securityOrigin of this._securityOriginManager.securityOrigins()) |
| 163 this._addOrigin(securityOrigin); |
| 164 |
| 165 this._enabled = true; |
| 166 } |
| 167 |
| 168 /** |
| 169 * @param {string} origin |
| 170 */ |
| 171 clearForOrigin(origin) { |
| 172 if (!this._enabled) |
| 173 return; |
| 174 |
| 175 this._removeOrigin(origin); |
| 176 this._addOrigin(origin); |
| 177 } |
| 178 |
| 179 refreshDatabaseNames() { |
| 180 for (var securityOrigin in this._databaseNamesBySecurityOrigin) |
| 181 this._loadDatabaseNames(securityOrigin); |
| 182 } |
| 183 |
| 184 /** |
| 185 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 186 */ |
| 187 refreshDatabase(databaseId) { |
| 188 this._loadDatabase(databaseId); |
| 189 } |
| 190 |
| 191 /** |
| 192 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 193 * @param {string} objectStoreName |
| 194 * @param {function()} callback |
| 195 */ |
| 196 clearObjectStore(databaseId, objectStoreName, callback) { |
| 197 this._agent.clearObjectStore(databaseId.securityOrigin, databaseId.name, obj
ectStoreName, callback); |
| 198 } |
| 199 |
| 200 /** |
| 201 * @param {!WebInspector.Event} event |
| 202 */ |
| 203 _securityOriginAdded(event) { |
| 204 var securityOrigin = /** @type {string} */ (event.data); |
| 205 this._addOrigin(securityOrigin); |
| 206 } |
| 207 |
| 208 /** |
| 209 * @param {!WebInspector.Event} event |
| 210 */ |
| 211 _securityOriginRemoved(event) { |
| 212 var securityOrigin = /** @type {string} */ (event.data); |
| 213 this._removeOrigin(securityOrigin); |
| 214 } |
| 215 |
| 216 /** |
| 217 * @param {string} securityOrigin |
| 218 */ |
| 219 _addOrigin(securityOrigin) { |
| 220 console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]); |
| 221 this._databaseNamesBySecurityOrigin[securityOrigin] = []; |
| 222 this._loadDatabaseNames(securityOrigin); |
| 223 } |
| 224 |
| 225 /** |
| 226 * @param {string} securityOrigin |
| 227 */ |
| 228 _removeOrigin(securityOrigin) { |
| 229 console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]); |
| 230 for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].leng
th; ++i) |
| 231 this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[
securityOrigin][i]); |
| 232 delete this._databaseNamesBySecurityOrigin[securityOrigin]; |
| 233 } |
| 234 |
| 235 /** |
| 236 * @param {string} securityOrigin |
| 237 * @param {!Array.<string>} databaseNames |
| 238 */ |
| 239 _updateOriginDatabaseNames(securityOrigin, databaseNames) { |
| 240 var newDatabaseNames = new Set(databaseNames); |
| 241 var oldDatabaseNames = new Set(this._databaseNamesBySecurityOrigin[securityO
rigin]); |
| 242 |
| 243 this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames; |
| 244 |
| 245 for (var databaseName of oldDatabaseNames) { |
| 246 if (!newDatabaseNames.has(databaseName)) |
| 247 this._databaseRemoved(securityOrigin, databaseName); |
| 248 } |
| 249 for (var databaseName of newDatabaseNames) { |
| 250 if (!oldDatabaseNames.has(databaseName)) |
| 251 this._databaseAdded(securityOrigin, databaseName); |
| 252 } |
| 253 } |
| 254 |
| 255 /** |
| 256 * @return {!Array.<!WebInspector.IndexedDBModel.DatabaseId>} |
| 257 */ |
| 258 databases() { |
| 259 var result = []; |
| 260 for (var securityOrigin in this._databaseNamesBySecurityOrigin) { |
| 261 var databaseNames = this._databaseNamesBySecurityOrigin[securityOrigin]; |
| 262 for (var i = 0; i < databaseNames.length; ++i) { |
| 263 result.push(new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, d
atabaseNames[i])); |
| 264 } |
| 265 } |
| 266 return result; |
| 267 } |
| 268 |
| 269 /** |
| 270 * @param {string} securityOrigin |
| 271 * @param {string} databaseName |
| 272 */ |
| 273 _databaseAdded(securityOrigin, databaseName) { |
| 274 var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin,
databaseName); |
| 275 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.DatabaseAdd
ed, databaseId); |
| 276 } |
| 277 |
| 278 /** |
| 279 * @param {string} securityOrigin |
| 280 * @param {string} databaseName |
| 281 */ |
| 282 _databaseRemoved(securityOrigin, databaseName) { |
| 283 var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin,
databaseName); |
| 284 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.DatabaseRem
oved, databaseId); |
| 285 } |
| 286 |
| 287 /** |
| 288 * @param {string} securityOrigin |
| 289 */ |
| 290 _loadDatabaseNames(securityOrigin) { |
| 291 /** |
| 292 * @param {?Protocol.Error} error |
| 293 * @param {!Array.<string>} databaseNames |
| 294 * @this {WebInspector.IndexedDBModel} |
| 295 */ |
| 296 function callback(error, databaseNames) { |
| 297 if (error) { |
| 298 console.error('IndexedDBAgent error: ' + error); |
| 299 return; |
| 300 } |
| 301 |
| 302 if (!this._databaseNamesBySecurityOrigin[securityOrigin]) |
| 303 return; |
| 304 this._updateOriginDatabaseNames(securityOrigin, databaseNames); |
| 305 } |
| 306 |
| 307 this._agent.requestDatabaseNames(securityOrigin, callback.bind(this)); |
| 308 } |
| 309 |
| 310 /** |
| 311 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 312 */ |
| 313 _loadDatabase(databaseId) { |
| 314 /** |
| 315 * @param {?Protocol.Error} error |
| 316 * @param {!IndexedDBAgent.DatabaseWithObjectStores} databaseWithObjectStore
s |
| 317 * @this {WebInspector.IndexedDBModel} |
| 318 */ |
| 319 function callback(error, databaseWithObjectStores) { |
| 320 if (error) { |
| 321 console.error('IndexedDBAgent error: ' + error); |
| 322 return; |
| 323 } |
| 324 |
| 325 if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) |
| 326 return; |
| 327 var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, d
atabaseWithObjectStores.version); |
| 328 this._databases.set(databaseId, databaseModel); |
| 329 for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) { |
| 330 var objectStore = databaseWithObjectStores.objectStores[i]; |
| 331 var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKe
yPath(objectStore.keyPath); |
| 332 var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore( |
| 333 objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement); |
| 334 for (var j = 0; j < objectStore.indexes.length; ++j) { |
| 335 var index = objectStore.indexes[j]; |
| 336 var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPat
h(index.keyPath); |
| 337 var indexModel = |
| 338 new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath,
index.unique, index.multiEntry); |
| 339 objectStoreModel.indexes[indexModel.name] = indexModel; |
| 340 } |
| 341 databaseModel.objectStores[objectStoreModel.name] = objectStoreModel; |
| 342 } |
| 343 |
| 344 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.DatabaseL
oaded, databaseModel); |
| 345 } |
| 346 |
| 347 this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name, call
back.bind(this)); |
| 348 } |
| 349 |
| 350 /** |
| 351 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 352 * @param {string} objectStoreName |
| 353 * @param {?IDBKeyRange} idbKeyRange |
| 354 * @param {number} skipCount |
| 355 * @param {number} pageSize |
| 356 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} cal
lback |
| 357 */ |
| 358 loadObjectStoreData(databaseId, objectStoreName, idbKeyRange, skipCount, pageS
ize, callback) { |
| 359 this._requestData(databaseId, databaseId.name, objectStoreName, '', idbKeyRa
nge, skipCount, pageSize, callback); |
| 360 } |
| 361 |
| 362 /** |
| 363 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 364 * @param {string} objectStoreName |
| 365 * @param {string} indexName |
| 366 * @param {?IDBKeyRange} idbKeyRange |
| 367 * @param {number} skipCount |
| 368 * @param {number} pageSize |
| 369 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} cal
lback |
| 370 */ |
| 371 loadIndexData(databaseId, objectStoreName, indexName, idbKeyRange, skipCount,
pageSize, callback) { |
| 372 this._requestData( |
| 373 databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, sk
ipCount, pageSize, callback); |
| 374 } |
| 375 |
| 376 /** |
| 377 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 378 * @param {string} databaseName |
| 379 * @param {string} objectStoreName |
| 380 * @param {string} indexName |
| 381 * @param {?IDBKeyRange} idbKeyRange |
| 382 * @param {number} skipCount |
| 383 * @param {number} pageSize |
| 384 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} cal
lback |
| 385 */ |
| 386 _requestData(databaseId, databaseName, objectStoreName, indexName, idbKeyRange
, skipCount, pageSize, callback) { |
| 387 /** |
| 388 * @param {?Protocol.Error} error |
| 389 * @param {!Array.<!IndexedDBAgent.DataEntry>} dataEntries |
| 390 * @param {boolean} hasMore |
| 391 * @this {WebInspector.IndexedDBModel} |
| 392 */ |
| 393 function innerCallback(error, dataEntries, hasMore) { |
| 394 if (error) { |
| 395 console.error('IndexedDBAgent error: ' + error); |
| 396 return; |
| 397 } |
| 398 |
| 399 if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) |
| 400 return; |
| 401 var entries = []; |
| 402 for (var i = 0; i < dataEntries.length; ++i) { |
| 403 var key = this.target().runtimeModel.createRemoteObject(dataEntries[i].k
ey); |
| 404 var primaryKey = this.target().runtimeModel.createRemoteObject(dataEntri
es[i].primaryKey); |
| 405 var value = this.target().runtimeModel.createRemoteObject(dataEntries[i]
.value); |
| 406 entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, valu
e)); |
| 407 } |
| 408 callback(entries, hasMore); |
| 409 } |
| 410 |
| 411 var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRan
ge); |
| 412 this._agent.requestData( |
| 413 databaseId.securityOrigin, databaseName, objectStoreName, indexName, ski
pCount, pageSize, |
| 414 keyRange ? keyRange : undefined, innerCallback.bind(this)); |
| 415 } |
| 416 }; |
| 417 |
| 418 WebInspector.IndexedDBModel.KeyTypes = { |
| 419 NumberType: 'number', |
| 420 StringType: 'string', |
| 421 DateType: 'date', |
| 422 ArrayType: 'array' |
| 423 }; |
| 424 |
| 425 WebInspector.IndexedDBModel.KeyPathTypes = { |
| 426 NullType: 'null', |
| 427 StringType: 'string', |
| 428 ArrayType: 'array' |
| 429 }; |
| 430 |
157 | 431 |
158 /** @enum {symbol} */ | 432 /** @enum {symbol} */ |
159 WebInspector.IndexedDBModel.Events = { | 433 WebInspector.IndexedDBModel.Events = { |
160 DatabaseAdded: Symbol("DatabaseAdded"), | 434 DatabaseAdded: Symbol('DatabaseAdded'), |
161 DatabaseRemoved: Symbol("DatabaseRemoved"), | 435 DatabaseRemoved: Symbol('DatabaseRemoved'), |
162 DatabaseLoaded: Symbol("DatabaseLoaded") | 436 DatabaseLoaded: Symbol('DatabaseLoaded') |
163 }; | |
164 | |
165 WebInspector.IndexedDBModel.prototype = { | |
166 enable: function() | |
167 { | |
168 if (this._enabled) | |
169 return; | |
170 | |
171 this._agent.enable(); | |
172 this._securityOriginManager.addEventListener(WebInspector.SecurityOrigin
Manager.Events.SecurityOriginAdded, this._securityOriginAdded, this); | |
173 this._securityOriginManager.addEventListener(WebInspector.SecurityOrigin
Manager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this); | |
174 | |
175 for (var securityOrigin of this._securityOriginManager.securityOrigins()
) | |
176 this._addOrigin(securityOrigin); | |
177 | |
178 this._enabled = true; | |
179 }, | |
180 | |
181 /** | |
182 * @param {string} origin | |
183 */ | |
184 clearForOrigin: function(origin) | |
185 { | |
186 if (!this._enabled) | |
187 return; | |
188 | |
189 this._removeOrigin(origin); | |
190 this._addOrigin(origin); | |
191 }, | |
192 | |
193 refreshDatabaseNames: function() | |
194 { | |
195 for (var securityOrigin in this._databaseNamesBySecurityOrigin) | |
196 this._loadDatabaseNames(securityOrigin); | |
197 }, | |
198 | |
199 /** | |
200 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
201 */ | |
202 refreshDatabase: function(databaseId) | |
203 { | |
204 this._loadDatabase(databaseId); | |
205 }, | |
206 | |
207 /** | |
208 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
209 * @param {string} objectStoreName | |
210 * @param {function()} callback | |
211 */ | |
212 clearObjectStore: function(databaseId, objectStoreName, callback) | |
213 { | |
214 this._agent.clearObjectStore(databaseId.securityOrigin, databaseId.name,
objectStoreName, callback); | |
215 }, | |
216 | |
217 /** | |
218 * @param {!WebInspector.Event} event | |
219 */ | |
220 _securityOriginAdded: function(event) | |
221 { | |
222 var securityOrigin = /** @type {string} */ (event.data); | |
223 this._addOrigin(securityOrigin); | |
224 }, | |
225 | |
226 /** | |
227 * @param {!WebInspector.Event} event | |
228 */ | |
229 _securityOriginRemoved: function(event) | |
230 { | |
231 var securityOrigin = /** @type {string} */ (event.data); | |
232 this._removeOrigin(securityOrigin); | |
233 }, | |
234 | |
235 /** | |
236 * @param {string} securityOrigin | |
237 */ | |
238 _addOrigin: function(securityOrigin) | |
239 { | |
240 console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]); | |
241 this._databaseNamesBySecurityOrigin[securityOrigin] = []; | |
242 this._loadDatabaseNames(securityOrigin); | |
243 }, | |
244 | |
245 /** | |
246 * @param {string} securityOrigin | |
247 */ | |
248 _removeOrigin: function(securityOrigin) | |
249 { | |
250 console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]); | |
251 for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].
length; ++i) | |
252 this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityO
rigin[securityOrigin][i]); | |
253 delete this._databaseNamesBySecurityOrigin[securityOrigin]; | |
254 }, | |
255 | |
256 /** | |
257 * @param {string} securityOrigin | |
258 * @param {!Array.<string>} databaseNames | |
259 */ | |
260 _updateOriginDatabaseNames: function(securityOrigin, databaseNames) | |
261 { | |
262 var newDatabaseNames = new Set(databaseNames); | |
263 var oldDatabaseNames = new Set(this._databaseNamesBySecurityOrigin[secur
ityOrigin]); | |
264 | |
265 this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames; | |
266 | |
267 for (var databaseName of oldDatabaseNames) { | |
268 if (!newDatabaseNames.has(databaseName)) | |
269 this._databaseRemoved(securityOrigin, databaseName); | |
270 } | |
271 for (var databaseName of newDatabaseNames) { | |
272 if (!oldDatabaseNames.has(databaseName)) | |
273 this._databaseAdded(securityOrigin, databaseName); | |
274 } | |
275 }, | |
276 | |
277 /** | |
278 * @return {!Array.<!WebInspector.IndexedDBModel.DatabaseId>} | |
279 */ | |
280 databases: function() | |
281 { | |
282 var result = []; | |
283 for (var securityOrigin in this._databaseNamesBySecurityOrigin) { | |
284 var databaseNames = this._databaseNamesBySecurityOrigin[securityOrig
in]; | |
285 for (var i = 0; i < databaseNames.length; ++i) { | |
286 result.push(new WebInspector.IndexedDBModel.DatabaseId(securityO
rigin, databaseNames[i])); | |
287 } | |
288 } | |
289 return result; | |
290 }, | |
291 | |
292 /** | |
293 * @param {string} securityOrigin | |
294 * @param {string} databaseName | |
295 */ | |
296 _databaseAdded: function(securityOrigin, databaseName) | |
297 { | |
298 var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrig
in, databaseName); | |
299 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.Databas
eAdded, databaseId); | |
300 }, | |
301 | |
302 /** | |
303 * @param {string} securityOrigin | |
304 * @param {string} databaseName | |
305 */ | |
306 _databaseRemoved: function(securityOrigin, databaseName) | |
307 { | |
308 var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrig
in, databaseName); | |
309 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.Databas
eRemoved, databaseId); | |
310 }, | |
311 | |
312 /** | |
313 * @param {string} securityOrigin | |
314 */ | |
315 _loadDatabaseNames: function(securityOrigin) | |
316 { | |
317 /** | |
318 * @param {?Protocol.Error} error | |
319 * @param {!Array.<string>} databaseNames | |
320 * @this {WebInspector.IndexedDBModel} | |
321 */ | |
322 function callback(error, databaseNames) | |
323 { | |
324 if (error) { | |
325 console.error("IndexedDBAgent error: " + error); | |
326 return; | |
327 } | |
328 | |
329 if (!this._databaseNamesBySecurityOrigin[securityOrigin]) | |
330 return; | |
331 this._updateOriginDatabaseNames(securityOrigin, databaseNames); | |
332 } | |
333 | |
334 this._agent.requestDatabaseNames(securityOrigin, callback.bind(this)); | |
335 }, | |
336 | |
337 /** | |
338 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
339 */ | |
340 _loadDatabase: function(databaseId) | |
341 { | |
342 /** | |
343 * @param {?Protocol.Error} error | |
344 * @param {!IndexedDBAgent.DatabaseWithObjectStores} databaseWithObjectS
tores | |
345 * @this {WebInspector.IndexedDBModel} | |
346 */ | |
347 function callback(error, databaseWithObjectStores) | |
348 { | |
349 if (error) { | |
350 console.error("IndexedDBAgent error: " + error); | |
351 return; | |
352 } | |
353 | |
354 if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) | |
355 return; | |
356 var databaseModel = new WebInspector.IndexedDBModel.Database(databas
eId, databaseWithObjectStores.version); | |
357 this._databases.set(databaseId, databaseModel); | |
358 for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++
i) { | |
359 var objectStore = databaseWithObjectStores.objectStores[i]; | |
360 var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPa
thFromKeyPath(objectStore.keyPath); | |
361 var objectStoreModel = new WebInspector.IndexedDBModel.ObjectSto
re(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement); | |
362 for (var j = 0; j < objectStore.indexes.length; ++j) { | |
363 var index = objectStore.indexes[j]; | |
364 var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPath
FromKeyPath(index.keyPath); | |
365 var indexModel = new WebInspector.IndexedDBModel.Index(index
.name, indexIDBKeyPath, index.unique, index.multiEntry); | |
366 objectStoreModel.indexes[indexModel.name] = indexModel; | |
367 } | |
368 databaseModel.objectStores[objectStoreModel.name] = objectStoreM
odel; | |
369 } | |
370 | |
371 this.dispatchEventToListeners(WebInspector.IndexedDBModel.Events.Dat
abaseLoaded, databaseModel); | |
372 } | |
373 | |
374 this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name,
callback.bind(this)); | |
375 }, | |
376 | |
377 /** | |
378 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
379 * @param {string} objectStoreName | |
380 * @param {?IDBKeyRange} idbKeyRange | |
381 * @param {number} skipCount | |
382 * @param {number} pageSize | |
383 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} c
allback | |
384 */ | |
385 loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skip
Count, pageSize, callback) | |
386 { | |
387 this._requestData(databaseId, databaseId.name, objectStoreName, "", idbK
eyRange, skipCount, pageSize, callback); | |
388 }, | |
389 | |
390 /** | |
391 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
392 * @param {string} objectStoreName | |
393 * @param {string} indexName | |
394 * @param {?IDBKeyRange} idbKeyRange | |
395 * @param {number} skipCount | |
396 * @param {number} pageSize | |
397 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} c
allback | |
398 */ | |
399 loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange,
skipCount, pageSize, callback) | |
400 { | |
401 this._requestData(databaseId, databaseId.name, objectStoreName, indexNam
e, idbKeyRange, skipCount, pageSize, callback); | |
402 }, | |
403 | |
404 /** | |
405 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
406 * @param {string} databaseName | |
407 * @param {string} objectStoreName | |
408 * @param {string} indexName | |
409 * @param {?IDBKeyRange} idbKeyRange | |
410 * @param {number} skipCount | |
411 * @param {number} pageSize | |
412 * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} c
allback | |
413 */ | |
414 _requestData: function(databaseId, databaseName, objectStoreName, indexName,
idbKeyRange, skipCount, pageSize, callback) | |
415 { | |
416 /** | |
417 * @param {?Protocol.Error} error | |
418 * @param {!Array.<!IndexedDBAgent.DataEntry>} dataEntries | |
419 * @param {boolean} hasMore | |
420 * @this {WebInspector.IndexedDBModel} | |
421 */ | |
422 function innerCallback(error, dataEntries, hasMore) | |
423 { | |
424 if (error) { | |
425 console.error("IndexedDBAgent error: " + error); | |
426 return; | |
427 } | |
428 | |
429 if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin]) | |
430 return; | |
431 var entries = []; | |
432 for (var i = 0; i < dataEntries.length; ++i) { | |
433 var key = this.target().runtimeModel.createRemoteObject(dataEntr
ies[i].key); | |
434 var primaryKey = this.target().runtimeModel.createRemoteObject(d
ataEntries[i].primaryKey); | |
435 var value = this.target().runtimeModel.createRemoteObject(dataEn
tries[i].value); | |
436 entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryK
ey, value)); | |
437 } | |
438 callback(entries, hasMore); | |
439 } | |
440 | |
441 var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKe
yRange); | |
442 this._agent.requestData(databaseId.securityOrigin, databaseName, objectS
toreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, inner
Callback.bind(this)); | |
443 }, | |
444 | |
445 __proto__: WebInspector.SDKModel.prototype | |
446 }; | 437 }; |
447 | 438 |
448 /** | 439 /** |
449 * @constructor | 440 * @unrestricted |
450 * @param {!WebInspector.RemoteObject} key | |
451 * @param {!WebInspector.RemoteObject} primaryKey | |
452 * @param {!WebInspector.RemoteObject} value | |
453 */ | 441 */ |
454 WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value) | 442 WebInspector.IndexedDBModel.Entry = class { |
455 { | 443 /** |
| 444 * @param {!WebInspector.RemoteObject} key |
| 445 * @param {!WebInspector.RemoteObject} primaryKey |
| 446 * @param {!WebInspector.RemoteObject} value |
| 447 */ |
| 448 constructor(key, primaryKey, value) { |
456 this.key = key; | 449 this.key = key; |
457 this.primaryKey = primaryKey; | 450 this.primaryKey = primaryKey; |
458 this.value = value; | 451 this.value = value; |
| 452 } |
459 }; | 453 }; |
460 | 454 |
461 /** | 455 /** |
462 * @constructor | 456 * @unrestricted |
463 * @param {string} securityOrigin | |
464 * @param {string} name | |
465 */ | 457 */ |
466 WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name) | 458 WebInspector.IndexedDBModel.DatabaseId = class { |
467 { | 459 /** |
| 460 * @param {string} securityOrigin |
| 461 * @param {string} name |
| 462 */ |
| 463 constructor(securityOrigin, name) { |
468 this.securityOrigin = securityOrigin; | 464 this.securityOrigin = securityOrigin; |
469 this.name = name; | 465 this.name = name; |
470 }; | 466 } |
471 | 467 |
472 WebInspector.IndexedDBModel.DatabaseId.prototype = { | 468 /** |
473 /** | 469 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
474 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | 470 * @return {boolean} |
475 * @return {boolean} | 471 */ |
476 */ | 472 equals(databaseId) { |
477 equals: function(databaseId) | 473 return this.name === databaseId.name && this.securityOrigin === databaseId.s
ecurityOrigin; |
478 { | 474 } |
479 return this.name === databaseId.name && this.securityOrigin === database
Id.securityOrigin; | 475 }; |
480 }, | 476 |
481 }; | |
482 /** | 477 /** |
483 * @constructor | 478 * @unrestricted |
484 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId | |
485 * @param {number} version | |
486 */ | 479 */ |
487 WebInspector.IndexedDBModel.Database = function(databaseId, version) | 480 WebInspector.IndexedDBModel.Database = class { |
488 { | 481 /** |
| 482 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId |
| 483 * @param {number} version |
| 484 */ |
| 485 constructor(databaseId, version) { |
489 this.databaseId = databaseId; | 486 this.databaseId = databaseId; |
490 this.version = version; | 487 this.version = version; |
491 this.objectStores = {}; | 488 this.objectStores = {}; |
| 489 } |
492 }; | 490 }; |
493 | 491 |
494 /** | 492 /** |
495 * @constructor | 493 * @unrestricted |
496 * @param {string} name | |
497 * @param {*} keyPath | |
498 * @param {boolean} autoIncrement | |
499 */ | 494 */ |
500 WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement) | 495 WebInspector.IndexedDBModel.ObjectStore = class { |
501 { | 496 /** |
| 497 * @param {string} name |
| 498 * @param {*} keyPath |
| 499 * @param {boolean} autoIncrement |
| 500 */ |
| 501 constructor(name, keyPath, autoIncrement) { |
502 this.name = name; | 502 this.name = name; |
503 this.keyPath = keyPath; | 503 this.keyPath = keyPath; |
504 this.autoIncrement = autoIncrement; | 504 this.autoIncrement = autoIncrement; |
505 this.indexes = {}; | 505 this.indexes = {}; |
506 }; | 506 } |
507 | 507 |
508 WebInspector.IndexedDBModel.ObjectStore.prototype = { | 508 /** |
509 /** | 509 * @return {string} |
510 * @type {string} | 510 */ |
511 */ | 511 get keyPathString() { |
512 get keyPathString() | 512 return /** @type {string}*/ ( |
513 { | 513 WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(/** @type {strin
g}*/ (this.keyPath))); |
514 return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyP
ath); | 514 } |
515 } | |
516 }; | 515 }; |
517 | 516 |
518 /** | 517 /** |
519 * @constructor | 518 * @unrestricted |
520 * @param {string} name | |
521 * @param {*} keyPath | |
522 * @param {boolean} unique | |
523 * @param {boolean} multiEntry | |
524 */ | 519 */ |
525 WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry) | 520 WebInspector.IndexedDBModel.Index = class { |
526 { | 521 /** |
| 522 * @param {string} name |
| 523 * @param {*} keyPath |
| 524 * @param {boolean} unique |
| 525 * @param {boolean} multiEntry |
| 526 */ |
| 527 constructor(name, keyPath, unique, multiEntry) { |
527 this.name = name; | 528 this.name = name; |
528 this.keyPath = keyPath; | 529 this.keyPath = keyPath; |
529 this.unique = unique; | 530 this.unique = unique; |
530 this.multiEntry = multiEntry; | 531 this.multiEntry = multiEntry; |
531 }; | 532 } |
532 | 533 |
533 WebInspector.IndexedDBModel.Index.prototype = { | 534 /** |
534 /** | 535 * @return {string} |
535 * @type {string} | 536 */ |
536 */ | 537 get keyPathString() { |
537 get keyPathString() | 538 return /** @type {string}*/ ( |
538 { | 539 WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(/** @type {strin
g}*/ (this.keyPath))); |
539 return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyP
ath); | 540 } |
540 } | 541 }; |
541 }; | 542 |
542 | 543 |
543 /** | |
544 * @param {!WebInspector.Target} target | |
545 * @return {!WebInspector.IndexedDBModel} | |
546 */ | |
547 WebInspector.IndexedDBModel.fromTarget = function(target) | |
548 { | |
549 var model = /** @type {?WebInspector.IndexedDBModel} */ (target.model(WebIns
pector.IndexedDBModel)); | |
550 if (!model) | |
551 model = new WebInspector.IndexedDBModel(target, WebInspector.SecurityOri
ginManager.fromTarget(target)); | |
552 return model; | |
553 }; | |
OLD | NEW |