updraft
Version:
Javascript ORM-like storage in SQLite (WebSQL or other), synced to the cloud
147 lines (130 loc) • 4.55 kB
text/typescript
///<reference path="../typings/index.d.ts"/>
///<reference path="./Database.ts"/>
namespace Updraft {
interface WebsqlTransaction extends DbTransaction {
realTransaction: SQLTransaction;
errorCallback: DbErrorCallback;
}
/* istanbul ignore next: can't test websql in node */
class WebsqlWrapper implements DbWrapper {
db: Database;
traceCallback: (trace: string) => any;
constructor(name: string, version?: string, displayName?: string, estimatedSize?: number, traceCallback?: (trace: string) => any) {
version = version || "1.0";
displayName = displayName || name;
estimatedSize = estimatedSize || 5 * 1024 * 1024;
this.db = window.openDatabase(name, version, displayName, estimatedSize);
this.traceCallback = traceCallback;
}
trace(sql: string, params?: (string | number)[]) {
if (this.traceCallback) {
let escapedString = this.stringify(sql, params);
this.traceCallback(escapedString);
}
}
stringify(sql: string, params?: (string | number)[]): string {
let idx: number = 0;
let escapedString = sql.replace(/\?/g, () => {
let x = params[idx++];
if (typeof x == "number") {
return <string>x;
} else {
return "'" + x + "'";
}
});
return escapedString;
}
all(tx: WebsqlTransaction, sql: string, params: (string | number)[], callback: DbResultsCallback): void {
this.trace(sql, params);
try {
tx.realTransaction.executeSql(sql, params,
(transaction: SQLTransaction, resultSet: SQLResultSet) => {
let results: any[] = [];
for (let i = 0; i < resultSet.rows.length; i++) {
let row = resultSet.rows.item(i);
results.push(row);
}
callback(this.wrapTransaction(transaction, tx.errorCallback), results);
},
(transaction: SQLTransaction, error: SQLError) => {
console.error("error executing '" + this.stringify(sql, params) + "': ", error);
if (tx.errorCallback) {
tx.errorCallback(error as any);
}
else {
throw error;
}
return true;
}
);
}
catch (error) {
console.error("error executing '" + this.stringify(sql, params) + "': ", error);
if (tx.errorCallback) {
tx.errorCallback(error);
}
else {
throw error;
}
}
}
each(tx: WebsqlTransaction, sql: string, params: (string | number)[], callback: DbEachResultCallback, final: DbTransactionCallback) {
this.trace(sql, params);
tx.realTransaction.executeSql(sql, params,
(transaction: SQLTransaction, resultSet: SQLResultSet) => {
for (let i = 0; i < resultSet.rows.length; i++) {
let row = resultSet.rows.item(i);
if (callback) {
(function(row: any) {
callback(tx, row);
})(row);
}
}
final(this.wrapTransaction(transaction, tx.errorCallback));
},
(transaction: SQLTransaction, error: SQLError) => {
console.error("error executing '" + this.stringify(sql, params) + "': ", error);
if (tx.errorCallback) {
tx.errorCallback(error as any);
}
else {
throw error;
}
return true;
}
);
}
private wrapTransaction(transaction: SQLTransaction, errorCallback: DbErrorCallback): WebsqlTransaction {
let tx: WebsqlTransaction = {
realTransaction: transaction,
errorCallback: errorCallback,
executeSql: (sql: string, params?: (string | number)[], callback?: DbResultsCallback): void => {
this.all(tx, sql, params, callback);
},
each: (sql: string, params: (string | number)[], callback: DbEachResultCallback, final: DbTransactionCallback): void => {
this.each(tx, sql, params, callback, final);
},
commit: (cb: DbCommitCallback) => {
cb();
}
};
return tx;
}
transaction(callback: DbTransactionCallback, errorCallback: DbErrorCallback): void {
this.db.transaction((transaction: SQLTransaction) => {
let tx = this.wrapTransaction(transaction, errorCallback);
callback(tx);
});
}
readTransaction(callback: DbTransactionCallback, errorCallback: DbErrorCallback): void {
this.db.readTransaction((transaction: SQLTransaction) => {
let tx = this.wrapTransaction(transaction, errorCallback);
callback(tx);
});
}
}
/* istanbul ignore next: can't test websql in node */
export function createWebsqlWrapper(name: string, version?: string, displayName?: string, estimatedSize?: number, traceCallback?: (trace: string) => any): DbWrapper {
return new WebsqlWrapper(name, version, displayName, estimatedSize, traceCallback);
}
}