Merge pull request #5846 from manucorporat/refactor-storage

refactor(storage): improve code reuse and add clean() method
This commit is contained in:
Adam Bradley
2016-03-15 09:27:15 -05:00
3 changed files with 75 additions and 113 deletions

View File

@ -30,51 +30,62 @@ import {StorageEngine} from './storage';
* @see {@link /docs/v2/platform/storage/ Storage Platform Docs} * @see {@link /docs/v2/platform/storage/ Storage Platform Docs}
*/ */
export class LocalStorage extends StorageEngine { export class LocalStorage extends StorageEngine {
constructor(options={}) { constructor(options = {}) {
super(); super();
} }
/** /**
* Get the value of a key in LocalStorage * Get the value of a key in LocalStorage
* @param {String} key the key you want to lookup in LocalStorage * @param {String} key the key you want to lookup in LocalStorage
*/ */
get(key: string): Promise<string> { get(key: string): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let value = window.localStorage.getItem(key); let value = window.localStorage.getItem(key);
resolve(value); resolve(value);
} catch(e) { } catch (e) {
reject(e); reject(e);
} }
}); });
} }
/** /**
* Set a key value pair and save it to LocalStorage * Set a key value pair and save it to LocalStorage
* @param {String} key the key you want to save to LocalStorage * @param {String} key the key you want to save to LocalStorage
* @param {Any} value the value of the key you're saving * @param {Any} value the value of the key you're saving
*/ */
set(key: string, value: string): Promise<any> { set(key: string, value: string): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
window.localStorage.setItem(key, value); window.localStorage.setItem(key, value);
resolve(); resolve();
} catch(e) { } catch (e) {
reject(e); reject(e);
} }
}); });
} }
/** /**
* Remove a key from LocalStorage * Remove a key from LocalStorage
* @param {String} key the key you want to remove from LocalStorage * @param {String} key the key you want to remove from LocalStorage
*/ */
remove(key: string): Promise<any> { remove(key: string): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
window.localStorage.removeItem(key); window.localStorage.removeItem(key);
resolve(); resolve();
} catch(e) { } catch (e) {
reject(e);
}
});
}
clear(): Promise<any> {
return new Promise((resolve, reject) => {
try {
window.localStorage.clear();
resolve();
} catch (e) {
reject(e); reject(e);
} }
}); });

View File

@ -2,8 +2,8 @@ import {StorageEngine} from './storage';
import {defaults, assign} from '../../util/util'; import {defaults, assign} from '../../util/util';
const DB_NAME :string = '__ionicstorage'; const DB_NAME: string = '__ionicstorage';
const win :any = window; const win: any = window;
/** /**
* SqlStorage uses SQLite or WebSQL (development only!) to store data in a * SqlStorage uses SQLite or WebSQL (development only!) to store data in a
@ -36,13 +36,13 @@ const win :any = window;
* *
*/ */
export class SqlStorage extends StorageEngine { export class SqlStorage extends StorageEngine {
static BACKUP_LOCAL = 2; static BACKUP_LOCAL = 2;
static BACKUP_LIBRARY = 1; static BACKUP_LIBRARY = 1;
static BACKUP_DOCUMENTS = 0; static BACKUP_DOCUMENTS = 0;
private _db: any; private _db: any;
constructor(options={}) { constructor(options = {}) {
super(); super();
let dbOptions = defaults(options, { let dbOptions = defaults(options, {
@ -68,8 +68,8 @@ export class SqlStorage extends StorageEngine {
this._tryInit(); this._tryInit();
} }
_getBackupLocation(dbFlag: number) { _getBackupLocation(dbFlag: number): number {
switch(dbFlag) { switch (dbFlag) {
case SqlStorage.BACKUP_LOCAL: case SqlStorage.BACKUP_LOCAL:
return 2; return 2;
case SqlStorage.BACKUP_LIBRARY: case SqlStorage.BACKUP_LIBRARY:
@ -83,11 +83,8 @@ export class SqlStorage extends StorageEngine {
// Initialize the DB with our required tables // Initialize the DB with our required tables
_tryInit() { _tryInit() {
this._db.transaction((tx) => { this.query('CREATE TABLE IF NOT EXISTS kv (key text primary key, value text)').catch(err => {
tx.executeSql('CREATE TABLE IF NOT EXISTS kv (key text primary key, value text)', [], (tx, res) => { console.error('Storage: Unable to create initial storage tables', err.tx, err.err);
}, (tx, err) => {
console.error('Storage: Unable to create initial storage tables', tx, err);
});
}); });
} }
@ -100,26 +97,17 @@ export class SqlStorage extends StorageEngine {
* @param {array} params the additional params to use for query placeholders * @param {array} params the additional params to use for query placeholders
* @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)} * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
*/ */
query(query, params=[]): Promise<any> { query(query: string, params = []): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
this._db.transaction((tx) => { this._db.transaction((tx) => {
tx.executeSql(query, params, (tx, res) => { tx.executeSql(query, params,
resolve({ (tx, res) => resolve({ tx: tx, res: res }),
tx: tx, (tx, err) => reject({ tx: tx, err: err }));
res: res },
}); (err) => reject({ err: err }));
}, (tx, err) => { } catch (err) {
reject({ reject({ err: err });
tx: tx,
err: err
});
})
}, err => {
reject(err);
});
} catch(e) {
reject(e);
} }
}) })
} }
@ -130,28 +118,9 @@ export class SqlStorage extends StorageEngine {
* @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)} * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
*/ */
get(key: string): Promise<any> { get(key: string): Promise<any> {
return new Promise((resolve, reject) => { return this.query('select key, value from kv where key = ? limit 1', [key]).then(data => {
try { if (data.res.rows.length > 0) {
return data.res.rows.item(0);
this._db.transaction(tx => {
tx.executeSql("select key, value from kv where key = ? limit 1", [key], (tx, res) => {
if (res.rows.length > 0) {
let item = res.rows.item(0);
resolve(item.value);
}
resolve(null);
}, (tx, err) => {
reject({
tx: tx,
err: err
});
})
}, err => {
reject(err);
});
} catch(e) {
reject(e);
} }
}); });
} }
@ -163,24 +132,7 @@ export class SqlStorage extends StorageEngine {
* @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)} * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
*/ */
set(key: string, value: string): Promise<any> { set(key: string, value: string): Promise<any> {
return new Promise((resolve, reject) => { return this.query('insert or replace into kv(key, value) values (?, ?)', [key, value]);
try {
this._db.transaction(tx => {
tx.executeSql('insert or replace into kv(key, value) values (?, ?)', [key, value], (tx, res) => {
resolve();
}, (tx, err) => {
reject({
tx: tx,
err: err
});
})
}, err => {
reject(err);
});
} catch(e) {
reject(e);
}
});
} }
/** /**
@ -189,24 +141,10 @@ export class SqlStorage extends StorageEngine {
* @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)} * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
*/ */
remove(key: string): Promise<any> { remove(key: string): Promise<any> {
return new Promise((resolve, reject) => { return this.query('delete from kv where key = ?', [key]);
try { }
this._db.transaction(tx => {
tx.executeSql('delete from kv where key = ?', [key], (tx, res) => {
resolve();
}, (tx, err) => {
reject({
tx: tx,
err: err
});
})
}, err => {
reject(err);
});
} catch(e) {
reject(e);
}
});
clear(): Promise<any> {
return this.query('delete from kv');
} }
} }

View File

@ -11,15 +11,17 @@
* @private * @private
*/ */
export class Storage { export class Storage {
private _strategy: any; private _strategy: StorageEngine;
constructor(strategyCls: IStorageEngine, options?: any) { constructor(strategyCls: IStorageEngine, options?: any) {
this._strategy = new strategyCls(options); this._strategy = new strategyCls(options);
} }
get(key: string): any {
get(key: string): Promise<any> {
return this._strategy.get(key); return this._strategy.get(key);
} }
getJson(key: string): any {
getJson(key: string): Promise<any> {
return this.get(key).then(value => { return this.get(key).then(value => {
try { try {
return JSON.parse(value); return JSON.parse(value);
@ -29,6 +31,7 @@ export class Storage {
} }
}); });
} }
setJson(key: string, value: any): Promise<any> { setJson(key: string, value: any): Promise<any> {
try { try {
return this.set(key, JSON.stringify(value)); return this.set(key, JSON.stringify(value));
@ -36,37 +39,47 @@ export class Storage {
return Promise.reject(e); return Promise.reject(e);
} }
} }
set(key: string, value: any) { set(key: string, value: any) {
return this._strategy.set(key, value); return this._strategy.set(key, value);
} }
remove(key: string) { remove(key: string) {
return this._strategy.remove(key); return this._strategy.remove(key);
} }
query(query: string, params?: any) { query(query: string, params?: any) {
return this._strategy.query(query, params); return this._strategy.query(query, params);
} }
clear() {
return this._strategy.clear();
}
} }
export interface IStorageEngine { export interface IStorageEngine {
new(options: any): StorageEngine; new (options: any): StorageEngine;
} }
/** /**
* @private * @private
*/ */
export class StorageEngine { export class StorageEngine {
constructor(options={}) { constructor(options = {}) { }
}
get(key, value) { get(key: string): Promise<any> {
throw Error("get() not implemented for this storage engine"); throw Error("get() not implemented for this storage engine");
} }
set(key, value) { set(key: string, value: any): Promise<any> {
throw Error("set() not implemented for this storage engine"); throw Error("set() not implemented for this storage engine");
} }
remove(key) { remove(key: string): Promise<any> {
throw Error("remove() not implemented for this storage engine"); throw Error("remove() not implemented for this storage engine");
} }
query(query, params) { query(query: string, params?: any): Promise<any> {
throw Error("query() not implemented for this storage engine"); throw Error("query() not implemented for this storage engine");
} }
clear(): Promise<any> {
throw Error("clear() not implemented for this storage engine");
}
} }