91 lines
4.0 KiB
JavaScript
91 lines
4.0 KiB
JavaScript
'use strict';
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const util = require('./util');
|
|
const SqliteError = require('./sqlite-error');
|
|
|
|
let DEFAULT_ADDON;
|
|
|
|
function Database(filenameGiven, options) {
|
|
if (new.target == null) {
|
|
return new Database(filenameGiven, options);
|
|
}
|
|
|
|
// Apply defaults
|
|
let buffer;
|
|
if (Buffer.isBuffer(filenameGiven)) {
|
|
buffer = filenameGiven;
|
|
filenameGiven = ':memory:';
|
|
}
|
|
if (filenameGiven == null) filenameGiven = '';
|
|
if (options == null) options = {};
|
|
|
|
// Validate arguments
|
|
if (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');
|
|
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
|
|
if ('readOnly' in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
|
|
if ('memory' in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
|
|
|
|
// Interpret options
|
|
const filename = filenameGiven.trim();
|
|
const anonymous = filename === '' || filename === ':memory:';
|
|
const readonly = util.getBooleanOption(options, 'readonly');
|
|
const fileMustExist = util.getBooleanOption(options, 'fileMustExist');
|
|
const timeout = 'timeout' in options ? options.timeout : 5000;
|
|
const verbose = 'verbose' in options ? options.verbose : null;
|
|
const nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;
|
|
|
|
// Validate interpreted options
|
|
if (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');
|
|
if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
|
|
if (timeout > 0x7fffffff) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
|
|
if (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the "verbose" option to be a function');
|
|
if (nativeBinding != null && typeof nativeBinding !== 'string' && typeof nativeBinding !== 'object') throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
|
|
|
|
// Load the native addon
|
|
let addon;
|
|
if (nativeBinding == null) {
|
|
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));
|
|
} else if (typeof nativeBinding === 'string') {
|
|
// See <https://webpack.js.org/api/module-variables/#__non_webpack_require__-webpack-specific>
|
|
const requireFunc = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require;
|
|
addon = requireFunc(path.resolve(nativeBinding).replace(/(\.node)?$/, '.node'));
|
|
} else {
|
|
// See <https://github.com/WiseLibs/better-sqlite3/issues/972>
|
|
addon = nativeBinding;
|
|
}
|
|
|
|
if (!addon.isInitialized) {
|
|
addon.setErrorConstructor(SqliteError);
|
|
addon.isInitialized = true;
|
|
}
|
|
|
|
// Make sure the specified directory exists
|
|
if (!anonymous && !fs.existsSync(path.dirname(filename))) {
|
|
throw new TypeError('Cannot open database because the directory does not exist');
|
|
}
|
|
|
|
Object.defineProperties(this, {
|
|
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
|
|
...wrappers.getters,
|
|
});
|
|
}
|
|
|
|
const wrappers = require('./methods/wrappers');
|
|
Database.prototype.prepare = wrappers.prepare;
|
|
Database.prototype.transaction = require('./methods/transaction');
|
|
Database.prototype.pragma = require('./methods/pragma');
|
|
Database.prototype.backup = require('./methods/backup');
|
|
Database.prototype.serialize = require('./methods/serialize');
|
|
Database.prototype.function = require('./methods/function');
|
|
Database.prototype.aggregate = require('./methods/aggregate');
|
|
Database.prototype.table = require('./methods/table');
|
|
Database.prototype.loadExtension = wrappers.loadExtension;
|
|
Database.prototype.exec = wrappers.exec;
|
|
Database.prototype.close = wrappers.close;
|
|
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
|
|
Database.prototype.unsafeMode = wrappers.unsafeMode;
|
|
Database.prototype[util.inspect] = require('./methods/inspect');
|
|
|
|
module.exports = Database;
|