Issue #640 - extract database code to dedicated package
This commit is contained in:
parent
f9cb631acb
commit
f9570ea3c5
5 changed files with 363 additions and 240 deletions
179
src/js/database/BackupDatabase.js
Normal file
179
src/js/database/BackupDatabase.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
(function () {
|
||||
var ns = $.namespace('pskl.database');
|
||||
|
||||
var DB_NAME = 'PiskelSessionsDatabase';
|
||||
var DB_VERSION = 1;
|
||||
|
||||
// Simple wrapper to promisify a request.
|
||||
var _requestPromise = function (req) {
|
||||
var deferred = Q.defer();
|
||||
req.onsuccess = deferred.resolve.bind(deferred);
|
||||
req.onerror = deferred.reject.bind(deferred);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* The BackupDatabase handles all the database interactions related
|
||||
* to piskel snapshots continuously saved while during the usage of
|
||||
* Piskel.
|
||||
*
|
||||
* @param {Object} options
|
||||
* - onUpgrade {Function} optional callback called when a DB
|
||||
* upgrade is performed.
|
||||
*/
|
||||
ns.BackupDatabase = function (options) {
|
||||
options = options || {};
|
||||
|
||||
this.db = null;
|
||||
this.onUpgrade = options.onUpgrade;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open and initialize the database.
|
||||
*/
|
||||
ns.BackupDatabase.prototype.init = function () {
|
||||
this.initDeferred_ = Q.defer();
|
||||
|
||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onerror = this.onRequestError_.bind(this);
|
||||
request.onsuccess = this.onRequestSuccess_.bind(this);
|
||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
||||
|
||||
return this.initDeferred_.promise;
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.onRequestError_ = function (event) {
|
||||
console.log('Could not initialize the piskel backup database');
|
||||
this.initDeferred_.reject();
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.onRequestSuccess_ = function (event) {
|
||||
this.db = event.target.result;
|
||||
this.initDeferred_.resolve(this.db);
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.onUpgradeNeeded_ = function (event) {
|
||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
||||
this.db = event.target.result;
|
||||
|
||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
||||
var objectStore = this.db.createObjectStore('snapshots', { keyPath: 'id', autoIncrement : true });
|
||||
|
||||
objectStore.createIndex('session_id', 'session_id', { unique: false });
|
||||
objectStore.createIndex('date', 'date', { unique: false });
|
||||
objectStore.createIndex('session_id, date', ['session_id', 'date'], { unique: false });
|
||||
|
||||
objectStore.transaction.oncomplete = function(event) {
|
||||
if (typeof this.onUpgrade == 'function') {
|
||||
this.onUpgrade(this.db);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.openObjectStore_ = function () {
|
||||
return this.db.transaction(['snapshots'], 'readwrite').objectStore('snapshots');
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an add request for the provided snapshot.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.BackupDatabase.prototype.createSnapshot = function (snapshot) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.add(snapshot);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a put request for the provided snapshot.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.BackupDatabase.prototype.updateSnapshot = function (snapshot) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.put(snapshot);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a delete request for the provided snapshot.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.BackupDatabase.prototype.deleteSnapshot = function (snapshot) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.delete(snapshot.id);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the last (most recent) snapshot that satisfies the accept filter provided.
|
||||
* Returns a promise that will resolve with the first matching snapshot (or null
|
||||
* if no valid snapshot is found).
|
||||
*
|
||||
* @param {Function} accept:
|
||||
* Filter method that takes a snapshot as argument and should return true
|
||||
* if the snapshot is valid.
|
||||
*/
|
||||
ns.BackupDatabase.prototype.findLastSnapshot = function (accept) {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
var index = objectStore.index('date');
|
||||
var range = IDBKeyRange.upperBound(Infinity);
|
||||
index.openCursor(range, 'prev').onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
var snapshot = cursor && cursor.value;
|
||||
|
||||
// Resolve null if we couldn't find a matching snapshot.
|
||||
if (!snapshot) {
|
||||
deferred.resolve(null);
|
||||
} else if (accept(snapshot)) {
|
||||
deferred.resolve(snapshot);
|
||||
} else {
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve all the snapshots for a given session id, sorted by descending date order.
|
||||
* Returns a promise that resolves with an array of snapshots.
|
||||
*
|
||||
* @param {String} sessionId
|
||||
* The session id
|
||||
*/
|
||||
ns.BackupDatabase.prototype.getSnapshotsBySessionId = function (sessionId) {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
// Loop on all the saved snapshots for the provided piskel id
|
||||
var index = objectStore.index('session_id, date');
|
||||
var keyRange = IDBKeyRange.bound(
|
||||
[sessionId, 0],
|
||||
[sessionId, Infinity]
|
||||
);
|
||||
|
||||
var snapshots = [];
|
||||
// Ordered by date in descending order.
|
||||
index.openCursor(keyRange, 'prev').onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
snapshots.push(cursor.value);
|
||||
cursor.continue();
|
||||
} else {
|
||||
console.log('consumed all piskel snapshots');
|
||||
deferred.resolve(snapshots);
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
})();
|
157
src/js/database/PiskelDatabase.js
Normal file
157
src/js/database/PiskelDatabase.js
Normal file
|
@ -0,0 +1,157 @@
|
|||
(function () {
|
||||
var ns = $.namespace('pskl.database');
|
||||
|
||||
var DB_NAME = 'PiskelDatabase';
|
||||
var DB_VERSION = 1;
|
||||
|
||||
// Simple wrapper to promisify a request.
|
||||
var _requestPromise = function (req) {
|
||||
var deferred = Q.defer();
|
||||
req.onsuccess = deferred.resolve.bind(deferred);
|
||||
req.onerror = deferred.reject.bind(deferred);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* The PiskelDatabase handles all the database interactions related
|
||||
* to the local piskel saved that can be performed in-browser.
|
||||
*
|
||||
* @param {Object} options
|
||||
* - onUpgrade {Function} optional callback called when a DB
|
||||
* upgrade is performed.
|
||||
*/
|
||||
ns.PiskelDatabase = function (options) {
|
||||
options = options || {};
|
||||
|
||||
this.db = null;
|
||||
this.onUpgrade = options.onUpgrade;
|
||||
};
|
||||
|
||||
ns.PiskelDatabase.prototype.init = function () {
|
||||
this.initDeferred_ = Q.defer();
|
||||
|
||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onerror = this.onRequestError_.bind(this);
|
||||
request.onsuccess = this.onRequestSuccess_.bind(this);
|
||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
||||
|
||||
return this.initDeferred_.promise;
|
||||
};
|
||||
|
||||
ns.PiskelDatabase.prototype.onRequestError_ = function (event) {
|
||||
console.log('Failed to initialize IndexedDB, local browser saves will be unavailable.');
|
||||
this.initDeferred_.reject();
|
||||
};
|
||||
|
||||
ns.PiskelDatabase.prototype.onRequestSuccess_ = function (event) {
|
||||
console.log('Successfully initialized IndexedDB, local browser saves are available.');
|
||||
this.db = event.target.result;
|
||||
this.initDeferred_.resolve(this.db);
|
||||
};
|
||||
|
||||
ns.PiskelDatabase.prototype.onUpgradeNeeded_ = function (event) {
|
||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
||||
this.db = event.target.result;
|
||||
|
||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
||||
var objectStore = this.db.createObjectStore('piskels', { keyPath : 'name' });
|
||||
objectStore.transaction.oncomplete = function(event) {
|
||||
if (typeof this.onUpgrade == 'function') {
|
||||
this.onUpgrade(this.db);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
ns.PiskelDatabase.prototype.openObjectStore_ = function () {
|
||||
return this.db.transaction(['piskels'], 'readwrite').objectStore('piskels');
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a get request for the provided name.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.PiskelDatabase.prototype.get = function (name) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
return _requestPromise(objectStore.get(name));
|
||||
};
|
||||
|
||||
/**
|
||||
* List all locally saved piskels.
|
||||
* Returns a promise that resolves an array of objects:
|
||||
* - name: name of the piskel
|
||||
* - description: description of the piskel
|
||||
* - date: save date
|
||||
*
|
||||
* The sprite content is not contained in the object and
|
||||
* needs to be retrieved with a separate get.
|
||||
*/
|
||||
ns.PiskelDatabase.prototype.list = function () {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var piskels = [];
|
||||
var objectStore = this.openObjectStore_();
|
||||
var cursor = objectStore.openCursor();
|
||||
cursor.onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
piskels.push({
|
||||
name: cursor.value.name,
|
||||
date: cursor.value.date,
|
||||
description: cursor.value.description
|
||||
});
|
||||
cursor.continue();
|
||||
} else {
|
||||
// Cursor consumed all availabled piskels
|
||||
deferred.resolve(piskels);
|
||||
}
|
||||
};
|
||||
|
||||
cursor.onerror = function () {
|
||||
deferred.reject();
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an put request for the provided args.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.PiskelDatabase.prototype.update = function (name, description, date, serialized) {
|
||||
var data = {};
|
||||
|
||||
data.name = name;
|
||||
data.serialized = serialized;
|
||||
data.date = date;
|
||||
data.description = description;
|
||||
|
||||
var objectStore = this.openObjectStore_();
|
||||
return _requestPromise(objectStore.put(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an add request for the provided args.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.PiskelDatabase.prototype.create = function (name, description, date, serialized) {
|
||||
var data = {};
|
||||
|
||||
data.name = name;
|
||||
data.serialized = serialized;
|
||||
data.date = date;
|
||||
data.description = description;
|
||||
|
||||
var objectStore = this.openObjectStore_();
|
||||
return _requestPromise(objectStore.add(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a saved piskel for the provided name.
|
||||
* Returns a promise that resolves the request event.
|
||||
*/
|
||||
ns.PiskelDatabase.prototype.delete = function (name) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
return _requestPromise(objectStore.delete(name));
|
||||
};
|
||||
})();
|
|
@ -1,9 +1,6 @@
|
|||
(function () {
|
||||
var ns = $.namespace('pskl.service');
|
||||
|
||||
var DB_NAME = 'PiskelSessionsDatabase';
|
||||
var DB_VERSION = 1;
|
||||
|
||||
var ONE_SECOND = 1000;
|
||||
var ONE_MINUTE = 60 * ONE_SECOND;
|
||||
|
||||
|
@ -14,104 +11,18 @@
|
|||
// Store up to 12 snapshots for a piskel session, min. 1 hour of work
|
||||
var MAX_SNAPSHOTS_PER_SESSION = 12;
|
||||
|
||||
var _requestPromise = function (req) {
|
||||
var deferred = Q.defer();
|
||||
req.onsuccess = deferred.resolve.bind(deferred);
|
||||
req.onerror = deferred.reject.bind(deferred);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ns.BackupService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.lastHash = null;
|
||||
this.nextSnapshotDate = -1;
|
||||
|
||||
this.backupDatabase = new pskl.database.BackupDatabase();
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.init = function () {
|
||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onerror = this.onRequestError_.bind(this);
|
||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
||||
request.onsuccess = this.onRequestSuccess_.bind(this);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.onRequestError_ = function (event) {
|
||||
console.log('Could not initialize the piskel backup database');
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.onUpgradeNeeded_ = function (event) {
|
||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
||||
this.db = event.target.result;
|
||||
|
||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
||||
var objectStore = this.db.createObjectStore('snapshots', { keyPath: 'id', autoIncrement : true });
|
||||
|
||||
objectStore.createIndex('session_id', 'session_id', { unique: false });
|
||||
objectStore.createIndex('date', 'date', { unique: false });
|
||||
objectStore.createIndex('session_id, date', ['session_id', 'date'], { unique: false });
|
||||
|
||||
objectStore.transaction.oncomplete = function(event) {
|
||||
// TODO: Migrate existing data from local storage?
|
||||
};
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.onRequestSuccess_ = function (event) {
|
||||
this.db = event.target.result;
|
||||
window.setInterval(this.backup.bind(this), BACKUP_INTERVAL);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.openObjectStore_ = function () {
|
||||
return this.db.transaction(['snapshots'], 'readwrite').objectStore('snapshots');
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.createSnapshot = function (snapshot) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.add(snapshot);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.replaceSnapshot = function (snapshot, replacedSnapshot) {
|
||||
snapshot.id = replacedSnapshot.id;
|
||||
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.put(snapshot);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.deleteSnapshot = function (snapshot) {
|
||||
var objectStore = this.openObjectStore_();
|
||||
var request = objectStore.delete(snapshot.id);
|
||||
return _requestPromise(request);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.getSnapshotsBySessionId_ = function (sessionId) {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
// Loop on all the saved snapshots for the provided piskel id
|
||||
var index = objectStore.index('session_id, date');
|
||||
var keyRange = IDBKeyRange.bound(
|
||||
[sessionId, 0],
|
||||
[sessionId, Infinity]
|
||||
);
|
||||
|
||||
var snapshots = [];
|
||||
// Ordered by date in descending order.
|
||||
index.openCursor(keyRange, 'prev').onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
snapshots.push(cursor.value);
|
||||
cursor.continue();
|
||||
} else {
|
||||
console.log('consumed all piskel snapshots');
|
||||
deferred.resolve(snapshots);
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
this.backupDatabase.init().then(function () {
|
||||
window.setInterval(this.backup.bind(this), BACKUP_INTERVAL);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.backup = function () {
|
||||
|
@ -138,19 +49,20 @@
|
|||
serialized: pskl.utils.serialization.Serializer.serialize(piskel)
|
||||
};
|
||||
|
||||
this.getSnapshotsBySessionId_(piskel.sessionId).then(function (snapshots) {
|
||||
this.backupDatabase.getSnapshotsBySessionId(piskel.sessionId).then(function (snapshots) {
|
||||
var latest = snapshots[0];
|
||||
|
||||
if (latest && date < this.nextSnapshotDate) {
|
||||
// update the latest snapshot
|
||||
return this.replaceSnapshot(snapshot, latest);
|
||||
snapshot.id = latest.id;
|
||||
return this.backupDatabase.updateSnapshot(snapshot);
|
||||
} else {
|
||||
// add a new snapshot
|
||||
this.nextSnapshotDate = date + SNAPSHOT_INTERVAL;
|
||||
return this.createSnapshot(snapshot).then(function () {
|
||||
return this.backupDatabase.createSnapshot(snapshot).then(function () {
|
||||
if (snapshots.length >= MAX_SNAPSHOTS_PER_SESSION) {
|
||||
// remove oldest snapshot
|
||||
return this.deleteSnapshot(snapshots[snapshots.length - 1]);
|
||||
return this.backupDatabase.deleteSnapshot(snapshots[snapshots.length - 1]);
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
@ -161,27 +73,10 @@
|
|||
};
|
||||
|
||||
ns.BackupService.prototype.getPreviousPiskelInfo = function () {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
var sessionId = this.piskelController.getPiskel().sessionId;
|
||||
var index = objectStore.index('date');
|
||||
var range = IDBKeyRange.upperBound(Infinity);
|
||||
index.openCursor(range, 'prev').onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
var snapshot = cursor && cursor.value;
|
||||
if (snapshot && snapshot.session_id === sessionId) {
|
||||
// Skip snapshots for the current session.
|
||||
cursor.continue();
|
||||
} else {
|
||||
deferred.resolve(snapshot);
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
return this.backupDatabase.findLastSnapshot(function (snapshot) {
|
||||
return snapshot.session_id !== sessionId;
|
||||
});
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.load = function() {
|
||||
|
|
|
@ -5,14 +5,11 @@
|
|||
|
||||
ns.IndexedDbStorageService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.piskelDatabase = new pskl.database.PiskelDatabase();
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.init = function () {
|
||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onerror = this.onRequestError_.bind(this);
|
||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
||||
request.onsuccess = this.onRequestSuccess_.bind(this);
|
||||
this.piskelDatabase.init();
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.save = function (piskel) {
|
||||
|
@ -25,61 +22,18 @@
|
|||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.save_ = function (name, description, date, serialized) {
|
||||
var deferred = Q.defer();
|
||||
var objectStore = this.db.transaction(['piskels'], 'readwrite').objectStore('piskels');
|
||||
|
||||
var getRequest = objectStore.get(name);
|
||||
getRequest.onsuccess = function (event) {
|
||||
console.log('get request successful for name: ' + name);
|
||||
return this.piskelDatabase.get(name).then(function (event) {
|
||||
var data = event.target.result;
|
||||
if (typeof data !== 'undefined') {
|
||||
|
||||
data.serialized = serialized;
|
||||
data.date = date;
|
||||
data.description = description;
|
||||
|
||||
var putRequest = objectStore.put(data);
|
||||
putRequest.onerror = function(event) {
|
||||
console.log('put request failed for name: ' + name);
|
||||
deferred.reject();
|
||||
};
|
||||
putRequest.onsuccess = function(event) {
|
||||
console.log('put request successful for name: ' + name);
|
||||
deferred.resolve();
|
||||
};
|
||||
return this.piskelDatabase.update(name, description, date, serialized);
|
||||
} else {
|
||||
var request = objectStore.add({
|
||||
name: name,
|
||||
description: description,
|
||||
serialized: serialized,
|
||||
date: date
|
||||
});
|
||||
|
||||
request.onerror = function(event) {
|
||||
console.log('Failed to save a piskel');
|
||||
deferred.reject();
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
console.log('Successfully saved a piskel');
|
||||
deferred.resolve();
|
||||
};
|
||||
return this.piskelDatabase.create(name, description, date, serialized);
|
||||
}
|
||||
};
|
||||
|
||||
getRequest.onerror = function () {
|
||||
console.log('get request failed for name: ' + name);
|
||||
deferred.reject();
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.load = function (name) {
|
||||
var objectStore = this.db.transaction(['piskels'], 'readwrite').objectStore('piskels');
|
||||
|
||||
var getRequest = objectStore.get(name);
|
||||
getRequest.onsuccess = function (event) {
|
||||
console.log('get request successful for name: ' + name);
|
||||
this.piskelDatabase.get(name).then(function (event) {
|
||||
var data = event.target.result;
|
||||
if (typeof data !== 'undefined') {
|
||||
var serialized = data.serialized;
|
||||
|
@ -92,80 +46,14 @@
|
|||
} else {
|
||||
console.log('no local browser save found for name: ' + name);
|
||||
}
|
||||
};
|
||||
|
||||
getRequest.onerror = function () {
|
||||
console.log('get request failed for name: ' + name);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.remove = function (name) {
|
||||
var objectStore = this.db.transaction(['piskels'], 'readwrite').objectStore('piskels');
|
||||
var deleteRequest = objectStore.delete(name);
|
||||
deleteRequest.onsuccess = function (event) {
|
||||
console.log('successfully deleted local browser save for name: ' + name);
|
||||
};
|
||||
|
||||
deleteRequest.onerror = function (event) {
|
||||
console.log('failed to delete local browser save for name: ' + name);
|
||||
};
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.list = function () {
|
||||
var deferred = Q.defer();
|
||||
var piskels = [];
|
||||
var objectStore = this.db.transaction(['piskels']).objectStore('piskels');
|
||||
|
||||
var cursor = objectStore.openCursor();
|
||||
cursor.onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
piskels.push({
|
||||
name: cursor.value.name,
|
||||
date: cursor.value.date,
|
||||
description: cursor.value.description
|
||||
});
|
||||
cursor.continue();
|
||||
} else {
|
||||
console.log('Cursor consumed all availabled piskels');
|
||||
deferred.resolve(piskels);
|
||||
}
|
||||
};
|
||||
|
||||
cursor.onerror = function () {
|
||||
deferred.reject();
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
this.piskelDatabase.delete(name);
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.getKeys = function () {
|
||||
return this.list();
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.onRequestError_ = function (event) {
|
||||
console.log('Failed to initialize IndexedDB, local browser saves will be unavailable.');
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.onRequestSuccess_ = function (event) {
|
||||
this.db = event.target.result;
|
||||
console.log('Successfully initialized IndexedDB, local browser saves are available.');
|
||||
};
|
||||
|
||||
ns.IndexedDbStorageService.prototype.onUpgradeNeeded_ = function (event) {
|
||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
||||
this.db = event.target.result;
|
||||
|
||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
||||
var objectStore = this.db.createObjectStore('piskels', { keyPath : 'name' });
|
||||
objectStore.transaction.oncomplete = function(event) {
|
||||
// Migrate existing sprites from LocalStorage
|
||||
pskl.service.storage.migrate.MigrateLocalStorageToIndexedDb.migrate().then(function () {
|
||||
console.log('Successfully migrated local storage data to indexed db');
|
||||
}).catch(function (e) {
|
||||
console.log('Failed to migrate local storage data to indexed db');
|
||||
console.error(e);
|
||||
});
|
||||
};
|
||||
return this.piskelDatabase.list();
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -79,6 +79,10 @@
|
|||
"js/model/Palette.js",
|
||||
"js/model/Piskel.js",
|
||||
|
||||
// Database (IndexedDB)
|
||||
"js/database/BackupDatabase.js",
|
||||
"js/database/PiskelDatabase.js",
|
||||
|
||||
// Selection
|
||||
"js/selection/SelectionManager.js",
|
||||
"js/selection/BaseSelection.js",
|
||||
|
|
Loading…
Reference in a new issue