'use strict';
var Queue = require('tiny-queue');
var immediate = require('immediate');
var noop = require('noop-fn');
var WebSQLTransaction = require('./WebSQLTransaction');
var ROLLBACK = [
{sql: 'ROLLBACK;', args: []}
];
var COMMIT = [
{sql: 'END;', args: []}
];
// v8 likes predictable objects
function TransactionTask(readOnly, txnCallback, errorCallback, successCallback) {
this.readOnly = readOnly;
this.txnCallback = txnCallback;
this.errorCallback = errorCallback;
this.successCallback = successCallback;
}
function WebSQLDatabase(dbVersion, db) {
this.version = dbVersion;
this._db = db;
this._txnQueue = new Queue();
this._running = false;
this._currentTask = null;
}
WebSQLDatabase.prototype._onTransactionComplete = function(err) {
var self = this;
function done() {
if (err) {
self._currentTask.errorCallback(err);
} else {
self._currentTask.successCallback();
}
self._running = false;
self._currentTask = null;
self._runNextTransaction();
}
if (self._currentTask.readOnly) {
done(); // read-only doesn't require a transaction
} else if (err) {
self._db.exec(ROLLBACK, false, done);
} else {
self._db.exec(COMMIT, false, done);
}
};
WebSQLDatabase.prototype._runTransaction = function () {
var self = this;
var txn = new WebSQLTransaction(self);
immediate(function () {
self._currentTask.txnCallback(txn);
txn._checkDone();
});
};
WebSQLDatabase.prototype._runNextTransaction = function() {
if (this._running) {
return;
}
var task = this._txnQueue.shift();
if (!task) {
return;
}
this._currentTask = task;
this._running = true;
this._runTransaction();
};
WebSQLDatabase.prototype._createTransaction = function(
readOnly, txnCallback, errorCallback, successCallback) {
errorCallback = errorCallback || noop;
successCallback = successCallback || noop;
if (typeof txnCallback !== 'function') {
throw new Error('The callback provided as parameter 1 is not a function.');
}
this._txnQueue.push(new TransactionTask(readOnly, txnCallback, errorCallback, successCallback));
this._runNextTransaction();
};
WebSQLDatabase.prototype.transaction = function (txnCallback, errorCallback, successCallback) {
this._createTransaction(false, txnCallback, errorCallback, successCallback);
};
WebSQLDatabase.prototype.readTransaction = function (txnCallback, errorCallback, successCallback) {
this._createTransaction(true, txnCallback, errorCallback, successCallback);
};
module.exports = WebSQLDatabase;