'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;