123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- (function (global, factory) {
- if (typeof define === "function" && define.amd) {
- define('webSQLStorage', ['module', 'exports', '../utils/isWebSQLValid', '../utils/serializer', '../utils/promise', '../utils/executeCallback', '../utils/normalizeKey', '../utils/getCallback'], factory);
- } else if (typeof exports !== "undefined") {
- factory(module, exports, require('../utils/isWebSQLValid'), require('../utils/serializer'), require('../utils/promise'), require('../utils/executeCallback'), require('../utils/normalizeKey'), require('../utils/getCallback'));
- } else {
- var mod = {
- exports: {}
- };
- factory(mod, mod.exports, global.isWebSQLValid, global.serializer, global.promise, global.executeCallback, global.normalizeKey, global.getCallback);
- global.webSQLStorage = mod.exports;
- }
- })(this, function (module, exports, _isWebSQLValid, _serializer, _promise, _executeCallback, _normalizeKey, _getCallback) {
- 'use strict';
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
-
- var _isWebSQLValid2 = _interopRequireDefault(_isWebSQLValid);
-
- var _serializer2 = _interopRequireDefault(_serializer);
-
- var _promise2 = _interopRequireDefault(_promise);
-
- var _executeCallback2 = _interopRequireDefault(_executeCallback);
-
- var _normalizeKey2 = _interopRequireDefault(_normalizeKey);
-
- var _getCallback2 = _interopRequireDefault(_getCallback);
-
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
-
- /*
- * Includes code from:
- *
- * base64-arraybuffer
- * https://github.com/niklasvh/base64-arraybuffer
- *
- * Copyright (c) 2012 Niklas von Hertzen
- * Licensed under the MIT license.
- */
-
- function createDbTable(t, dbInfo, callback, errorCallback) {
- t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' ' + '(id INTEGER PRIMARY KEY, key unique, value)', [], callback, errorCallback);
- }
-
- // Open the WebSQL database (automatically creates one if one didn't
- // previously exist), using any options set in the config.
- function _initStorage(options) {
- var self = this;
- var dbInfo = {
- db: null
- };
-
- if (options) {
- for (var i in options) {
- dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];
- }
- }
-
- var dbInfoPromise = new _promise2.default(function (resolve, reject) {
- // Open the database; the openDatabase API will automatically
- // create it for us if it doesn't exist.
- try {
- dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);
- } catch (e) {
- return reject(e);
- }
-
- // Create our key/value table if it doesn't exist.
- dbInfo.db.transaction(function (t) {
- createDbTable(t, dbInfo, function () {
- self._dbInfo = dbInfo;
- resolve();
- }, function (t, error) {
- reject(error);
- });
- }, reject);
- });
-
- dbInfo.serializer = _serializer2.default;
- return dbInfoPromise;
- }
-
- function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) {
- t.executeSql(sqlStatement, args, callback, function (t, error) {
- if (error.code === error.SYNTAX_ERR) {
- t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name = ?", [dbInfo.storeName], function (t, results) {
- if (!results.rows.length) {
- // if the table is missing (was deleted)
- // re-create it table and retry
- createDbTable(t, dbInfo, function () {
- t.executeSql(sqlStatement, args, callback, errorCallback);
- }, errorCallback);
- } else {
- errorCallback(t, error);
- }
- }, errorCallback);
- } else {
- errorCallback(t, error);
- }
- }, errorCallback);
- }
-
- function getItem(key, callback) {
- var self = this;
-
- key = (0, _normalizeKey2.default)(key);
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {
- var result = results.rows.length ? results.rows.item(0).value : null;
-
- // Check to see if this is serialized content we need to
- // unpack.
- if (result) {
- result = dbInfo.serializer.deserialize(result);
- }
-
- resolve(result);
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- function iterate(iterator, callback) {
- var self = this;
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
-
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {
- var rows = results.rows;
- var length = rows.length;
-
- for (var i = 0; i < length; i++) {
- var item = rows.item(i);
- var result = item.value;
-
- // Check to see if this is serialized content
- // we need to unpack.
- if (result) {
- result = dbInfo.serializer.deserialize(result);
- }
-
- result = iterator(result, item.key, i + 1);
-
- // void(0) prevents problems with redefinition
- // of `undefined`.
- if (result !== void 0) {
- resolve(result);
- return;
- }
- }
-
- resolve();
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- function _setItem(key, value, callback, retriesLeft) {
- var self = this;
-
- key = (0, _normalizeKey2.default)(key);
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- // The localStorage API doesn't return undefined values in an
- // "expected" way, so undefined is always cast to null in all
- // drivers. See: https://github.com/mozilla/localForage/pull/42
- if (value === undefined) {
- value = null;
- }
-
- // Save the original value to pass to the callback.
- var originalValue = value;
-
- var dbInfo = self._dbInfo;
- dbInfo.serializer.serialize(value, function (value, error) {
- if (error) {
- reject(error);
- } else {
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'INSERT OR REPLACE INTO ' + dbInfo.storeName + ' ' + '(key, value) VALUES (?, ?)', [key, value], function () {
- resolve(originalValue);
- }, function (t, error) {
- reject(error);
- });
- }, function (sqlError) {
- // The transaction failed; check
- // to see if it's a quota error.
- if (sqlError.code === sqlError.QUOTA_ERR) {
- // We reject the callback outright for now, but
- // it's worth trying to re-run the transaction.
- // Even if the user accepts the prompt to use
- // more storage on Safari, this error will
- // be called.
- //
- // Try to re-run the transaction.
- if (retriesLeft > 0) {
- resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));
- return;
- }
- reject(sqlError);
- }
- });
- }
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- function setItem(key, value, callback) {
- return _setItem.apply(this, [key, value, callback, 1]);
- }
-
- function removeItem(key, callback) {
- var self = this;
-
- key = (0, _normalizeKey2.default)(key);
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {
- resolve();
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- // Deletes every item in the table.
- // TODO: Find out if this resets the AUTO_INCREMENT number.
- function clear(callback) {
- var self = this;
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName, [], function () {
- resolve();
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- // Does a simple `COUNT(key)` to get the number of items stored in
- // localForage.
- function length(callback) {
- var self = this;
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- // Ahhh, SQL makes this one soooooo easy.
- tryExecuteSql(t, dbInfo, 'SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {
- var result = results.rows.item(0).c;
- resolve(result);
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- // Return the key located at key index X; essentially gets the key from a
- // `WHERE id = ?`. This is the most efficient way I can think to implement
- // this rarely-used (in my experience) part of the API, but it can seem
- // inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so
- // the ID of each key will change every time it's updated. Perhaps a stored
- // procedure for the `setItem()` SQL would solve this problem?
- // TODO: Don't change ID on `setItem()`.
- function key(n, callback) {
- var self = this;
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {
- var result = results.rows.length ? results.rows.item(0).key : null;
- resolve(result);
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- function keys(callback) {
- var self = this;
-
- var promise = new _promise2.default(function (resolve, reject) {
- self.ready().then(function () {
- var dbInfo = self._dbInfo;
- dbInfo.db.transaction(function (t) {
- tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {
- var keys = [];
-
- for (var i = 0; i < results.rows.length; i++) {
- keys.push(results.rows.item(i).key);
- }
-
- resolve(keys);
- }, function (t, error) {
- reject(error);
- });
- });
- }).catch(reject);
- });
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- // https://www.w3.org/TR/webdatabase/#databases
- // > There is no way to enumerate or delete the databases available for an origin from this API.
- function getAllStoreNames(db) {
- return new _promise2.default(function (resolve, reject) {
- db.transaction(function (t) {
- t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], function (t, results) {
- var storeNames = [];
-
- for (var i = 0; i < results.rows.length; i++) {
- storeNames.push(results.rows.item(i).name);
- }
-
- resolve({
- db: db,
- storeNames: storeNames
- });
- }, function (t, error) {
- reject(error);
- });
- }, function (sqlError) {
- reject(sqlError);
- });
- });
- }
-
- function dropInstance(options, callback) {
- callback = _getCallback2.default.apply(this, arguments);
-
- var currentConfig = this.config();
- options = typeof options !== 'function' && options || {};
- if (!options.name) {
- options.name = options.name || currentConfig.name;
- options.storeName = options.storeName || currentConfig.storeName;
- }
-
- var self = this;
- var promise;
- if (!options.name) {
- promise = _promise2.default.reject('Invalid arguments');
- } else {
- promise = new _promise2.default(function (resolve) {
- var db;
- if (options.name === currentConfig.name) {
- // use the db reference of the current instance
- db = self._dbInfo.db;
- } else {
- db = openDatabase(options.name, '', '', 0);
- }
-
- if (!options.storeName) {
- // drop all database tables
- resolve(getAllStoreNames(db));
- } else {
- resolve({
- db: db,
- storeNames: [options.storeName]
- });
- }
- }).then(function (operationInfo) {
- return new _promise2.default(function (resolve, reject) {
- operationInfo.db.transaction(function (t) {
- function dropTable(storeName) {
- return new _promise2.default(function (resolve, reject) {
- t.executeSql('DROP TABLE IF EXISTS ' + storeName, [], function () {
- resolve();
- }, function (t, error) {
- reject(error);
- });
- });
- }
-
- var operations = [];
- for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) {
- operations.push(dropTable(operationInfo.storeNames[i]));
- }
-
- _promise2.default.all(operations).then(function () {
- resolve();
- }).catch(function (e) {
- reject(e);
- });
- }, function (sqlError) {
- reject(sqlError);
- });
- });
- });
- }
-
- (0, _executeCallback2.default)(promise, callback);
- return promise;
- }
-
- var webSQLStorage = {
- _driver: 'webSQLStorage',
- _initStorage: _initStorage,
- _support: (0, _isWebSQLValid2.default)(),
- iterate: iterate,
- getItem: getItem,
- setItem: setItem,
- removeItem: removeItem,
- clear: clear,
- length: length,
- key: key,
- keys: keys,
- dropInstance: dropInstance
- };
-
- exports.default = webSQLStorage;
- module.exports = exports['default'];
- });
|