· 9 years ago · Dec 29, 2016, 05:00 AM
1import {Injectable} from "@angular/core";
2import {SQLite} from "ionic-native";
3
4const DB_NAME: string = '__rimsapp';
5const win: any = window;
6
7@Injectable()
8export class Sql {
9 private _db: any;
10
11 constructor() {
12 if (win.sqlitePlugin) {
13 let db = new SQLite();
14 this._db = db.openDatabase({
15 name: DB_NAME,
16 location: 'default'
17 });
18 } else {
19 console.warn('Storage: SQLite plugin not installed, falling back to WebSQL. Make sure to install cordova-sqlite-storage in production!');
20 this._db = win.openDatabase(DB_NAME, '1.0', 'database', 5 * 1024 * 1024);
21 }
22 this._tryInit();
23 }
24
25 // Initialize the DB with our required tables
26 _tryInit() {
27 this.query('CREATE TABLE IF NOT EXISTS kv (key text primary key, value text)').catch(err => {
28 console.error('Storage: Unable to create initial storage tables', err.tx, err.err);
29 });
30 }
31
32 /**
33 * Perform an arbitrary SQL operation on the database. Use this method
34 * to have full control over the underlying database through SQL operations
35 * like SELECT, INSERT, and UPDATE.
36 *
37 * @param {string} query the query to run
38 * @param {array} params the additional params to use for query placeholders
39 * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
40 */
41 query(query: string, params: any[] = []): Promise<any> {
42 return new Promise((resolve, reject) => {
43 try {
44 this._db.transaction((tx: any) => {
45 tx.executeSql(query, params,
46 (tx: any, res: any) => resolve({tx: tx, res: res}),
47 (tx: any, err: any) => reject({tx: tx, err: err}));
48 },
49 (err: any) => reject({err: err}));
50 } catch (err) {
51 reject({err: err});
52 }
53 });
54 }
55
56 /**
57 * Get the value in the database identified by the given key.
58 * @param {string} key the key
59 * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
60 */
61 get(key: string): Promise<any> {
62 return this.query('select key, value from kv where key = ? limit 1', [key]).then(data => {
63 if (data.res.rows.length > 0) {
64 return data.res.rows.item(0).value;
65 }
66 });
67 }
68
69 /**
70 * Set the value in the database for the given key. Existing values will be overwritten.
71 * @param {string} key the key
72 * @param {string} value The value (as a string)
73 * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
74 */
75 set(key: string, value: string): Promise<any> {
76 return this.query('insert or replace into kv(key, value) values (?, ?)', [key, value]);
77 }
78
79 getJson(key: string): Promise<any> {
80 return this.get(key).then(value => {
81 try {
82 return JSON.parse(value);
83 } catch (e) {
84 console.warn('Storage getJson(): unable to parse value for key', key, ' as JSON');
85 throw e; // rethrowing exception so it can be handled with .catch()
86 }
87 });
88 }
89
90 setJson(key: string, value: any): Promise<any> {
91 try {
92 return this.set(key, JSON.stringify(value));
93 } catch (e) {
94 return Promise.reject(e);
95 }
96 }
97
98 /**
99 * Remove the value in the database for the given key.
100 * @param {string} key the key
101 * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
102 */
103 remove(key: string): Promise<any> {
104 return this.query('delete from kv where key = ?', [key]);
105 }
106
107 /**
108 * Clear all keys/values of your database.
109 * @return {Promise} that resolves or rejects with an object of the form { tx: Transaction, res: Result (or err)}
110 */
111 clear(): Promise<any> {
112 return this.query('delete from kv');
113 }
114}