summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js')
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js506
1 files changed, 506 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js
new file mode 100644
index 00000000000..d79cfdc29f9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ */
+WebInspector.IndexedDBModel = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+ this._agent = target.indexedDBAgent();
+ this._agent.enable();
+
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
+
+ /** @type {!Map.<!WebInspector.IndexedDBModel.DatabaseId, !WebInspector.IndexedDBModel.Database>} */
+ this._databases = new Map();
+ /** @type {!Object.<string, !Array.<string>>} */
+ this._databaseNamesBySecurityOrigin = {};
+ this._reset();
+}
+
+WebInspector.IndexedDBModel.KeyTypes = {
+ NumberType: "number",
+ StringType: "string",
+ DateType: "date",
+ ArrayType: "array"
+};
+
+WebInspector.IndexedDBModel.KeyPathTypes = {
+ NullType: "null",
+ StringType: "string",
+ ArrayType: "array"
+};
+
+/**
+ * @param {*} idbKey
+ * @return {?Object}
+ */
+WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
+{
+ if (typeof(idbKey) === "undefined" || idbKey === null)
+ return null;
+
+ var key = {};
+ switch (typeof(idbKey)) {
+ case "number":
+ key.number = idbKey;
+ key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
+ break;
+ case "string":
+ key.string = idbKey;
+ key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
+ break;
+ case "object":
+ if (idbKey instanceof Date) {
+ key.date = idbKey.getTime();
+ key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
+ } else if (idbKey instanceof Array) {
+ key.array = [];
+ for (var i = 0; i < idbKey.length; ++i)
+ key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
+ key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
+ }
+ break;
+ default:
+ return null;
+ }
+ return key;
+}
+
+/**
+ * @param {?IDBKeyRange=} idbKeyRange
+ * @return {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}}
+ */
+WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
+{
+ if (typeof idbKeyRange === "undefined" || idbKeyRange === null)
+ return null;
+
+ var keyRange = {};
+ keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
+ keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
+ keyRange.lowerOpen = idbKeyRange.lowerOpen;
+ keyRange.upperOpen = idbKeyRange.upperOpen;
+ return keyRange;
+}
+
+/**
+ * @param {!IndexedDBAgent.KeyPath} keyPath
+ * @return {?string|!Array.<string>|undefined}
+ */
+WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
+{
+ var idbKeyPath;
+ switch (keyPath.type) {
+ case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
+ idbKeyPath = null;
+ break;
+ case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
+ idbKeyPath = keyPath.string;
+ break;
+ case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
+ idbKeyPath = keyPath.array;
+ break;
+ }
+ return idbKeyPath;
+}
+
+/**
+ * @param {?string|!Array.<string>|undefined} idbKeyPath
+ * @return {?string}
+ */
+WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
+{
+ if (typeof idbKeyPath === "string")
+ return "\"" + idbKeyPath + "\"";
+ if (idbKeyPath instanceof Array)
+ return "[\"" + idbKeyPath.join("\", \"") + "\"]";
+ return null;
+}
+
+WebInspector.IndexedDBModel.EventTypes = {
+ DatabaseAdded: "DatabaseAdded",
+ DatabaseRemoved: "DatabaseRemoved",
+ DatabaseLoaded: "DatabaseLoaded"
+}
+
+WebInspector.IndexedDBModel.prototype = {
+ _reset: function()
+ {
+ for (var securityOrigin in this._databaseNamesBySecurityOrigin)
+ this._removeOrigin(securityOrigin);
+ var securityOrigins = this.target().resourceTreeModel.securityOrigins();
+ for (var i = 0; i < securityOrigins.length; ++i)
+ this._addOrigin(securityOrigins[i]);
+ },
+
+ refreshDatabaseNames: function()
+ {
+ for (var securityOrigin in this._databaseNamesBySecurityOrigin)
+ this._loadDatabaseNames(securityOrigin);
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ */
+ refreshDatabase: function(databaseId)
+ {
+ this._loadDatabase(databaseId);
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @param {string} objectStoreName
+ * @param {function()} callback
+ */
+ clearObjectStore: function(databaseId, objectStoreName, callback)
+ {
+ this._agent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName, callback);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _securityOriginAdded: function(event)
+ {
+ var securityOrigin = /** @type {string} */ (event.data);
+ this._addOrigin(securityOrigin);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _securityOriginRemoved: function(event)
+ {
+ var securityOrigin = /** @type {string} */ (event.data);
+ this._removeOrigin(securityOrigin);
+ },
+
+ /**
+ * @param {string} securityOrigin
+ */
+ _addOrigin: function(securityOrigin)
+ {
+ console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]);
+ this._databaseNamesBySecurityOrigin[securityOrigin] = [];
+ this._loadDatabaseNames(securityOrigin);
+ },
+
+ /**
+ * @param {string} securityOrigin
+ */
+ _removeOrigin: function(securityOrigin)
+ {
+ console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]);
+ for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
+ this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
+ delete this._databaseNamesBySecurityOrigin[securityOrigin];
+ },
+
+ /**
+ * @param {string} securityOrigin
+ * @param {!Array.<string>} databaseNames
+ */
+ _updateOriginDatabaseNames: function(securityOrigin, databaseNames)
+ {
+ var newDatabaseNames = {};
+ for (var i = 0; i < databaseNames.length; ++i)
+ newDatabaseNames[databaseNames[i]] = true;
+ var oldDatabaseNames = {};
+ for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
+ oldDatabaseNames[this._databaseNamesBySecurityOrigin[securityOrigin][i]] = true;
+
+ this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;
+
+ for (var databaseName in oldDatabaseNames) {
+ if (!newDatabaseNames[databaseName])
+ this._databaseRemoved(securityOrigin, databaseName);
+ }
+ for (var databaseName in newDatabaseNames) {
+ if (!oldDatabaseNames[databaseName])
+ this._databaseAdded(securityOrigin, databaseName);
+ }
+ },
+
+ /**
+ * @param {string} securityOrigin
+ * @param {string} databaseName
+ */
+ _databaseAdded: function(securityOrigin, databaseName)
+ {
+ var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
+ this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
+ },
+
+ /**
+ * @param {string} securityOrigin
+ * @param {string} databaseName
+ */
+ _databaseRemoved: function(securityOrigin, databaseName)
+ {
+ var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
+ this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
+ },
+
+ /**
+ * @param {string} securityOrigin
+ */
+ _loadDatabaseNames: function(securityOrigin)
+ {
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!Array.<string>} databaseNames
+ * @this {WebInspector.IndexedDBModel}
+ */
+ function callback(error, databaseNames)
+ {
+ if (error) {
+ console.error("IndexedDBAgent error: " + error);
+ return;
+ }
+
+ if (!this._databaseNamesBySecurityOrigin[securityOrigin])
+ return;
+ this._updateOriginDatabaseNames(securityOrigin, databaseNames);
+ }
+
+ this._agent.requestDatabaseNames(securityOrigin, callback.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ */
+ _loadDatabase: function(databaseId)
+ {
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!IndexedDBAgent.DatabaseWithObjectStores} databaseWithObjectStores
+ * @this {WebInspector.IndexedDBModel}
+ */
+ function callback(error, databaseWithObjectStores)
+ {
+ if (error) {
+ console.error("IndexedDBAgent error: " + error);
+ return;
+ }
+
+ if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
+ return;
+ var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version, databaseWithObjectStores.intVersion);
+ this._databases.put(databaseId, databaseModel);
+ for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
+ var objectStore = databaseWithObjectStores.objectStores[i];
+ var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
+ var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
+ for (var j = 0; j < objectStore.indexes.length; ++j) {
+ var index = objectStore.indexes[j];
+ var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
+ var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
+ objectStoreModel.indexes[indexModel.name] = indexModel;
+ }
+ databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
+ }
+
+ this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
+ }
+
+ this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @param {string} objectStoreName
+ * @param {?IDBKeyRange} idbKeyRange
+ * @param {number} skipCount
+ * @param {number} pageSize
+ * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
+ */
+ loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
+ {
+ this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @param {string} objectStoreName
+ * @param {string} indexName
+ * @param {?IDBKeyRange} idbKeyRange
+ * @param {number} skipCount
+ * @param {number} pageSize
+ * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
+ */
+ loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
+ {
+ this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
+ },
+
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @param {string} databaseName
+ * @param {string} objectStoreName
+ * @param {string} indexName
+ * @param {?IDBKeyRange} idbKeyRange
+ * @param {number} skipCount
+ * @param {number} pageSize
+ * @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
+ */
+ _requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
+ {
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!Array.<!IndexedDBAgent.DataEntry>} dataEntries
+ * @param {boolean} hasMore
+ * @this {WebInspector.IndexedDBModel}
+ */
+ function innerCallback(error, dataEntries, hasMore)
+ {
+ if (error) {
+ console.error("IndexedDBAgent error: " + error);
+ return;
+ }
+
+ if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
+ return;
+ var entries = [];
+ for (var i = 0; i < dataEntries.length; ++i) {
+ var key = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].key));
+ var primaryKey = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].primaryKey));
+ var value = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].value));
+ entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
+ }
+ callback(entries, hasMore);
+ }
+
+ var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
+ this._agent.requestData(databaseId.securityOrigin, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.RemoteObject} key
+ * @param {!WebInspector.RemoteObject} primaryKey
+ * @param {!WebInspector.RemoteObject} value
+ */
+WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
+{
+ this.key = key;
+ this.primaryKey = primaryKey;
+ this.value = value;
+}
+
+/**
+ * @constructor
+ * @param {string} securityOrigin
+ * @param {string} name
+ */
+WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
+{
+ this.securityOrigin = securityOrigin;
+ this.name = name;
+}
+
+WebInspector.IndexedDBModel.DatabaseId.prototype = {
+ /**
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @return {boolean}
+ */
+ equals: function(databaseId)
+ {
+ return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
+ },
+}
+/**
+ * @constructor
+ * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @param {string} version
+ * @param {number} intVersion
+ */
+WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion)
+{
+ this.databaseId = databaseId;
+ this.version = version;
+ this.intVersion = intVersion;
+ this.objectStores = {};
+}
+
+/**
+ * @constructor
+ * @param {string} name
+ * @param {*} keyPath
+ * @param {boolean} autoIncrement
+ */
+WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
+{
+ this.name = name;
+ this.keyPath = keyPath;
+ this.autoIncrement = autoIncrement;
+ this.indexes = {};
+}
+
+WebInspector.IndexedDBModel.ObjectStore.prototype = {
+ /**
+ * @type {string}
+ */
+ get keyPathString()
+ {
+ return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
+ }
+}
+
+/**
+ * @constructor
+ * @param {string} name
+ * @param {*} keyPath
+ * @param {boolean} unique
+ * @param {boolean} multiEntry
+ */
+WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
+{
+ this.name = name;
+ this.keyPath = keyPath;
+ this.unique = unique;
+ this.multiEntry = multiEntry;
+}
+
+WebInspector.IndexedDBModel.Index.prototype = {
+ /**
+ * @type {string}
+ */
+ get keyPathString()
+ {
+ return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
+ }
+}