Skip to content

Commit

Permalink
Add option to set the default transaction behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
Abogical committed Aug 28, 2024
1 parent 7896456 commit a9eacaa
Show file tree
Hide file tree
Showing 9 changed files with 3,246 additions and 3,206 deletions.
5 changes: 4 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Various options are accepted:

- `options.timeout`: the number of milliseconds to wait when executing queries on a locked database, before throwing a `SQLITE_BUSY` error (default: `5000`).

- `options.defaultTransactionBehaviour`: Set the default transaction behavior when calling [Database#transaction()](#transactionfunction---function). Can be set as `null` (SQLite Default), `'deferred'`, `'immediate'` or `'exclusive'` (default: `null`).

- `options.verbose`: provide a function that gets called with every SQL string executed by the database connection (default: `null`).

- `options.nativeBinding`: if you're using a complicated build system that moves, transforms, or concatenates your JS files, `better-sqlite3` might have trouble locating its native C++ addon (`better_sqlite3.node`). If you get an error that looks like [this](https://github.com/JoshuaWise/better-sqlite3/issues/534#issuecomment-757907190), you can solve it by using this option to provide the file path of `better_sqlite3.node` (relative to the current working directory).
Expand Down Expand Up @@ -86,7 +88,8 @@ const adopt = db.transaction((cats) => {
Transactions also come with `deferred`, `immediate`, and `exclusive` versions.

```js
insertMany(cats); // uses "BEGIN"
insertMany(cats) // uses the default set by options.defaultTransactionBehavior
insertMany.default(cats); // uses "BEGIN"
insertMany.deferred(cats); // uses "BEGIN DEFERRED"
insertMany.immediate(cats); // uses "BEGIN IMMEDIATE"
insertMany.exclusive(cats); // uses "BEGIN EXCLUSIVE"
Expand Down
7 changes: 6 additions & 1 deletion lib/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,18 @@ function Database(filenameGiven, options) {
const timeout = 'timeout' in options ? options.timeout : 5000;
const verbose = 'verbose' in options ? options.verbose : null;
const nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;
const defaultTransactionBehavior = 'defaultTransactionBehavior' in options ? options.defaultTransactionBehavior : 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');
if (defaultTransactionBehavior != null) {
if (typeof defaultTransactionBehavior !== 'string') throw new TypeError('Expected the "defaultTransactionBehavior" option to be a string, expected "deferred", "immediate", or "exclusive"')
if (!["deferred", "immediate", "exclusive"].includes(defaultTransactionBehavior)) throw new Error('Invalid value for "defaultTransactionBehavior", expected "deferred", "immediate", or "exclusive"')
}

// Load the native addon
let addon;
Expand All @@ -66,7 +71,7 @@ function Database(filenameGiven, options) {
}

Object.defineProperties(this, {
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, defaultTransactionBehavior, verbose || null, buffer || null) },
...wrappers.getters,
});
}
Expand Down
4 changes: 3 additions & 1 deletion lib/methods/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ module.exports = function transaction(fn) {

// Each version of the transaction function has these same properties
const properties = {
default: { value: wrapTransaction(apply, fn, db, controller.default) },
deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
database: { value: this, enumerable: true },
};
properties.default = db.defaultTransactionBehavior == null ?
{ value: wrapTransaction(apply, fn, db, controller.default) } :
properties[db.defaultTransactionBehavior];

Object.defineProperties(properties.default.value, properties);
Object.defineProperties(properties.deferred.value, properties);
Expand Down
4 changes: 4 additions & 0 deletions lib/methods/wrappers.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ exports.getters = {
get: function memory() { return this[cppdb].memory; },
enumerable: true,
},
defaultTransactionBehavior: {
get: function defaultTransactionBehavior() { return this[cppdb].defaultTransactionBehavior; },
enumerable: true
}
};
Loading

0 comments on commit a9eacaa

Please sign in to comment.