database.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use strict';
  2. const fs = require('fs');
  3. const path = require('path');
  4. const util = require('./util');
  5. const SqliteError = require('./sqlite-error');
  6. let DEFAULT_ADDON;
  7. function Database(filenameGiven, options) {
  8. if (new.target == null) {
  9. return new Database(filenameGiven, options);
  10. }
  11. // Apply defaults
  12. let buffer;
  13. if (Buffer.isBuffer(filenameGiven)) {
  14. buffer = filenameGiven;
  15. filenameGiven = ':memory:';
  16. }
  17. if (filenameGiven == null) filenameGiven = '';
  18. if (options == null) options = {};
  19. // Validate arguments
  20. if (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');
  21. if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
  22. if ('readOnly' in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
  23. if ('memory' in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
  24. // Interpret options
  25. const filename = filenameGiven.trim();
  26. const anonymous = filename === '' || filename === ':memory:';
  27. const readonly = util.getBooleanOption(options, 'readonly');
  28. const fileMustExist = util.getBooleanOption(options, 'fileMustExist');
  29. const timeout = 'timeout' in options ? options.timeout : 5000;
  30. const verbose = 'verbose' in options ? options.verbose : null;
  31. const nativeBindingPath = 'nativeBinding' in options ? options.nativeBinding : null;
  32. // Validate interpreted options
  33. if (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');
  34. if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
  35. if (timeout > 0x7fffffff) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
  36. if (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the "verbose" option to be a function');
  37. if (nativeBindingPath != null && typeof nativeBindingPath !== 'string') throw new TypeError('Expected the "nativeBinding" option to be a string');
  38. // Load the native addon
  39. let addon;
  40. if (nativeBindingPath == null) {
  41. addon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));
  42. } else {
  43. addon = require(path.resolve(nativeBindingPath).replace(/(\.node)?$/, '.node'));
  44. }
  45. if (!addon.isInitialized) {
  46. addon.setErrorConstructor(SqliteError);
  47. addon.isInitialized = true;
  48. }
  49. // Make sure the specified directory exists
  50. if (!anonymous && !fs.existsSync(path.dirname(filename))) {
  51. throw new TypeError('Cannot open database because the directory does not exist');
  52. }
  53. Object.defineProperties(this, {
  54. [util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
  55. ...wrappers.getters,
  56. });
  57. }
  58. const wrappers = require('./methods/wrappers');
  59. Database.prototype.prepare = wrappers.prepare;
  60. Database.prototype.transaction = require('./methods/transaction');
  61. Database.prototype.pragma = require('./methods/pragma');
  62. Database.prototype.backup = require('./methods/backup');
  63. Database.prototype.serialize = require('./methods/serialize');
  64. Database.prototype.function = require('./methods/function');
  65. Database.prototype.aggregate = require('./methods/aggregate');
  66. Database.prototype.table = require('./methods/table');
  67. Database.prototype.loadExtension = wrappers.loadExtension;
  68. Database.prototype.exec = wrappers.exec;
  69. Database.prototype.close = wrappers.close;
  70. Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
  71. Database.prototype.unsafeMode = wrappers.unsafeMode;
  72. Database.prototype[util.inspect] = require('./methods/inspect');
  73. module.exports = Database;