module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/pawsqlite.mjs"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./src/database.mjs": /*!**************************!*\ !*** ./src/database.mjs ***! \**************************/ /*! exports provided: Database */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Database", function() { return Database; }); /* harmony import */ var _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transaction_manager.mjs */ "./src/transaction_manager.mjs"); class Database { constructor(dbName, adapter) { this.dbName = dbName; this.adapter = adapter; this.version = null; this.path = null; this.transactionManager = new _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__["TransactionManager"](dbName, this.adapter); } async open() { let response = await this.adapter.open(this.dbName); if (response) { if (response.hasOwnProperty('version')) { this.version = response.version; } if (response.hasOwnProperty('path')) { this.path = response.path; } } // Allow chaining return this; } close() { return this.adapter.close(this.dbName); } transaction() { return this.transactionManager.transaction(); } async autoTransaction(cb, inheritTx) { let tx = inheritTx || this.transaction(); let result; try { result = await cb(tx); } catch (e) { if (!inheritTx) { await tx.rollback(); } throw e; } if (!inheritTx) { await tx.commit(); } return result; } // Helper method to start a transaction and execute a single SQL statement sql(sql, ...args) { return this.autoTransaction((tx) => tx.sql(sql, ...args)); } } /***/ }), /***/ "./src/log.mjs": /*!*********************!*\ !*** ./src/log.mjs ***! \*********************/ /*! exports provided: log, enableDebug */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return log; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableDebug", function() { return enableDebug; }); let DEBUG = false; function log(...args) { if (DEBUG) { console.log(...args); } } function enableDebug(active) { DEBUG = !!active; log("PawSQLite: debugging " + (DEBUG ? "enabled" : "disabled")); } /***/ }), /***/ "./src/pawsqlite.mjs": /*!***************************!*\ !*** ./src/pawsqlite.mjs ***! \***************************/ /*! exports provided: default */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _database_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./database.mjs */ "./src/database.mjs"); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); /* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); const adapters = []; /* harmony default export */ __webpack_exports__["default"] = ({ open: async function(dbName, options = {}) { const adapter = getAdapter(options.adapter); let db = new _database_mjs__WEBPACK_IMPORTED_MODULE_0__["Database"](dbName, adapter); await db.open(); return db; }, delete: function(dbName, options = {}) { const adapter = getAdapter(options.adapter); return adapter.delete(dbName); }, registerAdapter: function(adapter) { adapters.push(wrapAdapter(adapter)); }, debug: _log_mjs__WEBPACK_IMPORTED_MODULE_2__["enableDebug"], Error: _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"] }); function wrapAdapter() { const wrapped = {}; ["name", "open", "close", "delete", "sql"].forEach((prop) => { if (!(prop in adapter)) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"](`Invalid adapter: missing property: ${ prop }`); } if ( prop === "name" && !( typeof adapter[prop] === "string" || adapter[prop] instanceof String ) || prop !== "name" && ( typeof adapter[prop] !== "function" ) ) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"]("Invalid adapter: invalid type for property: " + prop); } if (typeof adapter[prop] === "function") { wrapped[prop] = async (...args) => { try { return await adapter[prop](...args); } catch (err) { throw _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"].from(err); } }; } else { wrapped[prop] = adapter[prop]; } }); return wrapped; } function getAdapter(adapterName) { const adapter = adapters.find((a) => a.name === adapterName); if (!adapter) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"](`Unknown Adapter: ${adapterName}`); } return adapter; } /***/ }), /***/ "./src/pawsqlite_error.mjs": /*!*********************************!*\ !*** ./src/pawsqlite_error.mjs ***! \*********************************/ /*! exports provided: PawSQLiteError */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PawSQLiteError", function() { return PawSQLiteError; }); class PawSQLiteError extends Error { static from(err) { const p_err = new PawSQLiteError(err.toString()); p_err.cause = err; return p_err; } constructor(message) { super(message); this.name = "PawSQLiteError"; } } /***/ }), /***/ "./src/result.mjs": /*!************************!*\ !*** ./src/result.mjs ***! \************************/ /*! exports provided: Result */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Result", function() { return Result; }); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); class Result extends Array { constructor(result) { if (result.hasOwnProperty("rows")) { super(...result.rows); } else { super(); } if (result.hasOwnProperty("insertId")) { this.insertId = result.insertId; } if (result.hasOwnProperty("rowsAffected")) { this.rowsAffected = result.rowsAffected; } } } /***/ }), /***/ "./src/transaction.mjs": /*!*****************************!*\ !*** ./src/transaction.mjs ***! \*****************************/ /*! exports provided: Transaction */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Transaction", function() { return Transaction; }); /* harmony import */ var _result_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./result.mjs */ "./src/result.mjs"); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); class Transaction { constructor(dbName, adapter, enqueue, rollbackOnError=false) { this.dbName = dbName; this.adapter = adapter; this._rollbackOnError = rollbackOnError; this._enqueue = enqueue; this._completeCb = null; this._readyWait = null; this._ready = false; this._finalized = false; } async sql(sql, ...args) { if (this._finalized) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"]("Transaction has already completed"); } if (!this._ready) { await this._waitUntilReady(); } try { return await this._executeSQL(sql, ...args); } catch (e) { if (this._rollbackOnError) { await this.rollback(); } throw e; } } // Allow for slightly more complex parameter substitution. // Instances of "???" will be replaced by the same number of comma-separated // question marks as items in the corresponding nested parateter array // eg. buildQuery("SELECT (???) FROM ?", [["col1", "col2"], "table1"]) // would output: ["SELECT (?, ?) FROM ?", ["col1", "col2", "table1"]] buildQuery(sql, ...args) { const parts = sql.split("???"); const subParamLengths = args .filter(Array.isArray) .map((a) => a.length); if (parts.length !== subParamLengths.length + 1) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"]("Unable to build query: sub-" + "paramters do not match sub-paramters in query"); } const newQuery = parts.reduce((p1, p2, i) => { const length = subParamLengths[i - 1]; return p1 + new Array(length).fill("?").join(", ") + p2; }); const flatParams = args.reduce((acc, v) => { if (Array.isArray(v)) { Array.prototype.push.apply(acc, v); } else { acc.push(v); } return acc; }, []); return [newQuery, ...flatParams]; } commit() { return this._complete("COMMIT"); } rollback() { return this._complete("ROLLBACK"); } async _waitUntilReady() { if (!this._readyWait) { this._readyWait = (async () => { this._completeCb = await this._enqueue(); await this._begin(); this._ready = true; })(); } await this._readyWait; } async _executeSQL(sql, ...args) { const reg = /^\s*(BEGIN|END|COMMIT|ROLLBACK)(?:[^A-Z]|$)/i; const match = reg.exec(sql); if (match) { const statement = match[1].toUpperCase(); throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"]("Manually managing transactions is " + "forbidden. Found: \"" + statement + "\" statement."); } const result = await this.adapter.sql(this.dbName, ...this.buildQuery(sql, ...args)); return new _result_mjs__WEBPACK_IMPORTED_MODULE_0__["Result"](result); } async _begin() { const result = await this.adapter.sql(this.dbName, "BEGIN"); } async _complete(sql) { if (this._finalized) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__["PawSQLiteError"]("Transaction has already completed"); } this._finalized = true; if (!this._readyWait) { // Transaction was unused return; } else if (!this._ready) { await this._waitUntilReady(); } let result; let error; try { result = await this.adapter.sql(this.dbName, sql); } catch (e) { error = e; } this._completeCb(); if (error) { throw error; } return new _result_mjs__WEBPACK_IMPORTED_MODULE_0__["Result"](result); } } /***/ }), /***/ "./src/transaction_manager.mjs": /*!*************************************!*\ !*** ./src/transaction_manager.mjs ***! \*************************************/ /*! exports provided: TransactionManager */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransactionManager", function() { return TransactionManager; }); /* harmony import */ var _transaction_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transaction.mjs */ "./src/transaction.mjs"); class TransactionManager { constructor(dbName, adapter) { this.dbName = dbName; this.adapter = adapter; this._queue = []; this._inTransaction = false; } transaction() { return new _transaction_mjs__WEBPACK_IMPORTED_MODULE_0__["Transaction"](this.dbName, this.adapter, this.enqueue.bind(this)); } enqueue() { let completeSignal; let transactionComplete = new Promise((r, _) => { completeSignal = r; }); let readySignal; let dbReady = new Promise((r, _) => { readySignal = () => { r(completeSignal); }; }); this._queue.push({readySignal, transactionComplete}); this._processQueue(); return dbReady; } async _processQueue() { // We're already processing the queue if (this._inTransaction) { return; } while (true) { let item = this._queue.shift(); if (!item) { return; } this._inTransaction = true; item.readySignal(); await item.transactionComplete; this._inTransaction = false; } } } /***/ }) /******/ })["default"]; //# sourceMappingURL=PawSQLite.js.map