aboutsummaryrefslogtreecommitdiff
path: root/updater/sql/mac/lib/sqlite3.js
diff options
context:
space:
mode:
Diffstat (limited to 'updater/sql/mac/lib/sqlite3.js')
-rwxr-xr-xupdater/sql/mac/lib/sqlite3.js207
1 files changed, 207 insertions, 0 deletions
diff --git a/updater/sql/mac/lib/sqlite3.js b/updater/sql/mac/lib/sqlite3.js
new file mode 100755
index 0000000..430a2b8
--- /dev/null
+++ b/updater/sql/mac/lib/sqlite3.js
@@ -0,0 +1,207 @@
+const path = require('path');
+const sqlite3 = require('./sqlite3-binding.js');
+const EventEmitter = require('events').EventEmitter;
+module.exports = exports = sqlite3;
+
+function normalizeMethod (fn) {
+ return function (sql) {
+ let errBack;
+ const args = Array.prototype.slice.call(arguments, 1);
+
+ if (typeof args[args.length - 1] === 'function') {
+ const callback = args[args.length - 1];
+ errBack = function(err) {
+ if (err) {
+ callback(err);
+ }
+ };
+ }
+ const statement = new Statement(this, sql, errBack);
+ return fn.call(this, statement, args);
+ };
+}
+
+function inherits(target, source) {
+ for (const k in source.prototype)
+ target.prototype[k] = source.prototype[k];
+}
+
+sqlite3.cached = {
+ Database: function(file, a, b) {
+ if (file === '' || file === ':memory:') {
+ // Don't cache special databases.
+ return new Database(file, a, b);
+ }
+
+ let db;
+ file = path.resolve(file);
+
+ if (!sqlite3.cached.objects[file]) {
+ db = sqlite3.cached.objects[file] = new Database(file, a, b);
+ }
+ else {
+ // Make sure the callback is called.
+ db = sqlite3.cached.objects[file];
+ const callback = (typeof a === 'number') ? b : a;
+ if (typeof callback === 'function') {
+ function cb() { callback.call(db, null); }
+ if (db.open) process.nextTick(cb);
+ else db.once('open', cb);
+ }
+ }
+
+ return db;
+ },
+ objects: {}
+};
+
+
+const Database = sqlite3.Database;
+const Statement = sqlite3.Statement;
+const Backup = sqlite3.Backup;
+
+inherits(Database, EventEmitter);
+inherits(Statement, EventEmitter);
+inherits(Backup, EventEmitter);
+
+// Database#prepare(sql, [bind1, bind2, ...], [callback])
+Database.prototype.prepare = normalizeMethod(function(statement, params) {
+ return params.length
+ ? statement.bind.apply(statement, params)
+ : statement;
+});
+
+// Database#run(sql, [bind1, bind2, ...], [callback])
+Database.prototype.run = normalizeMethod(function(statement, params) {
+ statement.run.apply(statement, params).finalize();
+ return this;
+});
+
+// Database#get(sql, [bind1, bind2, ...], [callback])
+Database.prototype.get = normalizeMethod(function(statement, params) {
+ statement.get.apply(statement, params).finalize();
+ return this;
+});
+
+// Database#all(sql, [bind1, bind2, ...], [callback])
+Database.prototype.all = normalizeMethod(function(statement, params) {
+ statement.all.apply(statement, params).finalize();
+ return this;
+});
+
+// Database#each(sql, [bind1, bind2, ...], [callback], [complete])
+Database.prototype.each = normalizeMethod(function(statement, params) {
+ statement.each.apply(statement, params).finalize();
+ return this;
+});
+
+Database.prototype.map = normalizeMethod(function(statement, params) {
+ statement.map.apply(statement, params).finalize();
+ return this;
+});
+
+// Database#backup(filename, [callback])
+// Database#backup(filename, destName, sourceName, filenameIsDest, [callback])
+Database.prototype.backup = function() {
+ let backup;
+ if (arguments.length <= 2) {
+ // By default, we write the main database out to the main database of the named file.
+ // This is the most likely use of the backup api.
+ backup = new Backup(this, arguments[0], 'main', 'main', true, arguments[1]);
+ } else {
+ // Otherwise, give the user full control over the sqlite3_backup_init arguments.
+ backup = new Backup(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
+ }
+ // Per the sqlite docs, exclude the following errors as non-fatal by default.
+ backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
+ return backup;
+};
+
+Statement.prototype.map = function() {
+ const params = Array.prototype.slice.call(arguments);
+ const callback = params.pop();
+ params.push(function(err, rows) {
+ if (err) return callback(err);
+ const result = {};
+ if (rows.length) {
+ const keys = Object.keys(rows[0]);
+ const key = keys[0];
+ if (keys.length > 2) {
+ // Value is an object
+ for (let i = 0; i < rows.length; i++) {
+ result[rows[i][key]] = rows[i];
+ }
+ } else {
+ const value = keys[1];
+ // Value is a plain value
+ for (let i = 0; i < rows.length; i++) {
+ result[rows[i][key]] = rows[i][value];
+ }
+ }
+ }
+ callback(err, result);
+ });
+ return this.all.apply(this, params);
+};
+
+let isVerbose = false;
+
+const supportedEvents = [ 'trace', 'profile', 'change' ];
+
+Database.prototype.addListener = Database.prototype.on = function(type) {
+ const val = EventEmitter.prototype.addListener.apply(this, arguments);
+ if (supportedEvents.indexOf(type) >= 0) {
+ this.configure(type, true);
+ }
+ return val;
+};
+
+Database.prototype.removeListener = function(type) {
+ const val = EventEmitter.prototype.removeListener.apply(this, arguments);
+ if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
+ this.configure(type, false);
+ }
+ return val;
+};
+
+Database.prototype.removeAllListeners = function(type) {
+ const val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
+ if (supportedEvents.indexOf(type) >= 0) {
+ this.configure(type, false);
+ }
+ return val;
+};
+
+// Save the stack trace over EIO callbacks.
+sqlite3.verbose = function() {
+ if (!isVerbose) {
+ const trace = require('./trace');
+ [
+ 'prepare',
+ 'get',
+ 'run',
+ 'all',
+ 'each',
+ 'map',
+ 'close',
+ 'exec'
+ ].forEach(function (name) {
+ trace.extendTrace(Database.prototype, name);
+ });
+ [
+ 'bind',
+ 'get',
+ 'run',
+ 'all',
+ 'each',
+ 'map',
+ 'reset',
+ 'finalize',
+ ].forEach(function (name) {
+ trace.extendTrace(Statement.prototype, name);
+ });
+ isVerbose = true;
+ }
+
+ return sqlite3;
+};