diff --git a/README.md b/README.md index 68490f8f..ec892f0a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Downloads](https://img.shields.io/npm/dt/better-sqlite3-multiple-ciphers?logo=DocuSign&logoColor=FFF&color=2757c4&style=for-the-badge)](https://www.npmjs.com/package/better-sqlite3-multiple-ciphers) [![Build status](https://img.shields.io/github/actions/workflow/status/m4heshd/better-sqlite3-multiple-ciphers/test.yml?branch=master&label=Build%2FTest&logo=github&style=for-the-badge)](https://github.com/m4heshd/better-sqlite3-multiple-ciphers/actions/workflows/test.yml) -The fastest and simplest library for SQLite3 in Node.js. This particular fork supports multiple-cipher encryption using [SQLite3MultipleCiphers](https://github.com/utelle/SQLite3MultipleCiphers). Check [usage](#usage) to learn more. +The fastest and simplest library for SQLite in Node.js. This particular fork supports multiple-cipher encryption using [SQLite3MultipleCiphers](https://github.com/utelle/SQLite3MultipleCiphers). Check [usage](#usage) to learn more. - Full transaction support - High performance, efficiency, and safety @@ -158,7 +158,7 @@ uses [SQLite3MultipleCiphers](https://github.com/utelle/SQLite3MultipleCiphers) #### When is this library not appropriate? -In most cases, if you're attempting something that cannot be reasonably accomplished with `better-sqlite3`, it probably cannot be reasonably accomplished with SQLite3 in general. For example, if you're executing queries that take one second to complete, and you expect to have many concurrent users executing those queries, no amount of asynchronicity will save you from SQLite3's serialized nature. Fortunately, SQLite3 is very *very* fast. With proper indexing, we've been able to achieve upward of 2000 queries per second with 5-way-joins in a 60 GB database, where each query was handling 5–50 kilobytes of real data. +In most cases, if you're attempting something that cannot be reasonably accomplished with `better-sqlite3`, it probably cannot be reasonably accomplished with SQLite in general. For example, if you're executing queries that take one second to complete, and you expect to have many concurrent users executing those queries, no amount of asynchronicity will save you from SQLite's serialized nature. Fortunately, SQLite is very *very* fast. With proper indexing, we've been able to achieve upward of 2000 queries per second with 5-way-joins in a 60 GB database, where each query was handling 5–50 kilobytes of real data. If you have a performance problem, the most likely causes are inefficient queries, improper indexing, or a lack of [WAL mode](./docs/performance.md)—not `better-sqlite3` itself. However, there are some cases where `better-sqlite3` could be inappropriate: @@ -170,10 +170,10 @@ For these situations, you should probably use a full-fledged RDBMS such as [Post ## Upgrading -Upgrading your `better-sqlite3-multiple-ciphers` dependency can potentially introduce breaking changes, either in the `better-sqlite3-multiple-ciphers` API, or between your existing database(s) and the underlying version of SQLite. Before upgrading, review: +Upgrading your `better-sqlite3-multiple-ciphers` dependency can potentially introduce breaking changes, either in the `better-sqlite3-multiple-ciphers` API (if you upgrade to a new [major version](https://semver.org/)), or between your existing database(s) and the underlying version of SQLite. Before upgrading, review: -* `better-sqlite3-multiple-ciphers` release notes: https://github.com/WiseLibs/better-sqlite3-multiple-ciphers/releases -* SQLite changelog: https://www.sqlite.org/changes.html +* [`better-sqlite3-multiple-ciphers` release notes](https://github.com/m4heshd/better-sqlite3-multiple-ciphers/releases) +* [SQLite release history](https://www.sqlite.org/changes.html) # Documentation @@ -182,7 +182,7 @@ Upgrading your `better-sqlite3-multiple-ciphers` dependency can potentially intr - [64-bit integer support](./docs/integer.md) - [Worker thread support](./docs/threads.md) - [Unsafe mode (advanced)](./docs/unsafe.md) -- [SQLite3 compilation](./docs/compilation.md) +- [SQLite compilation (advanced)](./docs/compilation.md) # License diff --git a/benchmark/drivers.js b/benchmark/drivers.js index 60e5a189..d2a43d53 100644 --- a/benchmark/drivers.js +++ b/benchmark/drivers.js @@ -1,7 +1,7 @@ 'use strict'; /* - Every benchmark trial will be executed once for each SQLite3 driver listed + Every benchmark trial will be executed once for each SQLite driver listed below. Each driver has a function to open a new database connection on a given filename and a list of PRAGMA statements. */ diff --git a/binding.gyp b/binding.gyp index aedfe47c..660872ed 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,5 +1,5 @@ # === -# This is the main GYP file, which builds better-sqlite3 with SQLite3 itself. +# This is the main GYP file, which builds better-sqlite3 with SQLite itself. # === { diff --git a/deps/sqlite3.gyp b/deps/sqlite3.gyp index 4032a63f..e2f14b79 100755 --- a/deps/sqlite3.gyp +++ b/deps/sqlite3.gyp @@ -1,5 +1,5 @@ # === -# This configuration defines options specific to compiling SQLite3 itself. +# This configuration defines options specific to compiling SQLite itself. # Compile-time options are loaded by the auto-generated file "defines.gypi". # The --sqlite3 option can be provided to use a custom amalgamation instead. # === diff --git a/deps/test_extension.c b/deps/test_extension.c index 1f5c5710..540aad2c 100644 --- a/deps/test_extension.c +++ b/deps/test_extension.c @@ -2,7 +2,7 @@ SQLITE_EXTENSION_INIT1 /* - This SQLite3 extension is used only for testing purposes (npm test). + This SQLite extension is used only for testing purposes (npm test). */ static void TestExtensionFunction(sqlite3_context* pCtx, int nVal, sqlite3_value** _) { diff --git a/deps/update-sqlite3mc.sh b/deps/update-sqlite3mc.sh index 819c1d85..6532ae2b 100644 --- a/deps/update-sqlite3mc.sh +++ b/deps/update-sqlite3mc.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash # === -# This script defines and generates the bundled SQLite3 unit (sqlite3.c). +# This script defines and generates the bundled SQLite unit (sqlite3.c). # # The following steps are taken: # 1. populate the shell environment with the defined compile-time options. -# 2. download and extract the SQLite3 source code into a temporary directory. +# 2. download and extract the SQLite source code into a temporary directory. # 3. run "sh configure" and "make sqlite3.c" within the source directory. -# 4. clone the SQLite3MultipleCiphers repo, replace SQLite3 amalgamation and patch it. +# 4. clone the SQLite3MultipleCiphers repo, replace SQLite amalgamation and patch it. # 5. build the SQLite3MultipleCiphers amalgamation # 6. copy the generated amalgamation into the output directory (./sqlite3). # 7. export the defined compile-time options to a gyp file (./defines.gypi). @@ -76,17 +76,17 @@ mkdir -p "$TEMP" mkdir -p "$OUTPUT" export CFLAGS=`echo $(echo "$DEFINES" | sed -e "/^\s*$/d" -e "s/^/-D/")` -echo -e "\nDownloading SQLite3 source..." +echo -e "\nDownloading SQLite source..." curl -#f "https://www.sqlite.org/$YEAR/sqlite-src-$VERSION.zip" > "$TEMP/source.zip" || exit 1 -echo -e "\nExtracting SQLite3 source..." +echo -e "\nExtracting SQLite source..." unzip "$TEMP/source.zip" -d "$TEMP" > /dev/null || exit 1 cd "$TEMP/sqlite-src-$VERSION" || exit 1 -echo -e "\nConfiguring SQLite3 amalgamation..." +echo -e "\nConfiguring SQLite amalgamation..." sh configure > /dev/null || exit 1 -echo -e "\nBuilding SQLite3 amalgamation..." +echo -e "\nBuilding SQLite amalgamation..." make OPTIONS="$CFLAGS" sqlite3.c > /dev/null || exit 1 echo -e "\nCloning SQLite3MultipleCiphers repo..." @@ -95,11 +95,11 @@ git clone --quiet https://github.com/utelle/SQLite3MultipleCiphers.git > /dev/nu cd "$TEMP/SQLite3MultipleCiphers" || exit 1 git checkout --quiet "tags/$SQLITE3MC_VERSION" > /dev/null || exit 1 -echo -e "\nReplacing SQLite3 amalgamation in SQLite3MultipleCiphers..." +echo -e "\nReplacing SQLite amalgamation in SQLite3MultipleCiphers..." cd "$TEMP/sqlite-src-$VERSION" || exit 1 (yes | cp -rf sqlite3.c sqlite3.h sqlite3ext.h "$TEMP/SQLite3MultipleCiphers/src") || exit 1 -echo -e "\nPatching SQLite3 amalgamation in SQLite3MultipleCiphers..." +echo -e "\nPatching SQLite amalgamation in SQLite3MultipleCiphers..." cd "$TEMP/SQLite3MultipleCiphers" || exit 1 chmod +x ./scripts/patchsqlite3.sh || exit 1 chmod +x ./scripts/rekeyvacuum.sh || exit 1 @@ -137,4 +137,4 @@ echo -e "\nCleaning up..." cd - > /dev/null || exit 1 rm -rf "$TEMP" -echo -e "\nSQLite3MC update process completed!" +echo -e "\nSQLite3MultipleCiphers update process completed!" diff --git a/docs/api.md b/docs/api.md index e1286b66..462200cd 100644 --- a/docs/api.md +++ b/docs/api.md @@ -39,7 +39,7 @@ Various options are accepted: - `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-multiple-ciphers` 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/146#issue-337752663), you can solve it by using this option to provide the file path of `better_sqlite3.node` (relative to the current working directory). +- `options.nativeBinding`: if you're using a complicated build system that moves, transforms, or concatenates your JS files, `better-sqlite3-multiple-ciphers` 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). ```js const Database = require('better-sqlite3-multiple-ciphers'); @@ -100,9 +100,9 @@ Any arguments passed to the transaction function will be forwarded to the wrappe If you'd like to manage transactions manually, you're free to do so with regular [prepared statements](#preparestring---statement) (using `BEGIN`, `COMMIT`, etc.). However, manually managed transactions should not be mixed with transactions managed by this `.transaction()` method. In other words, using raw `COMMIT` or `ROLLBACK` statements inside a transaction function is not supported. -Transaction functions do not work with async functions. Technically speaking, async functions always return after the first `await`, which means the transaction will already be committed before any async code executes. Also, because SQLite3 serializes all transactions, it's generally a very bad idea to keep a transaction open across event loop ticks anyways. +Transaction functions do not work with async functions. Technically speaking, async functions always return after the first `await`, which means the transaction will already be committed before any async code executes. Also, because SQLite serializes all transactions, it's generally a very bad idea to keep a transaction open across event loop ticks anyways. -It's important to know that SQLite3 may sometimes rollback a transaction without us asking it to. This can happen either because of an [`ON CONFLICT`](https://sqlite.org/lang_conflict.html) clause, the [`RAISE()`](https://www.sqlite.org/lang_createtrigger.html) trigger function, or certain errors such as `SQLITE_FULL` or `SQLITE_BUSY`. In other words, if you catch an SQLite3 error *within* a transaction, you must be aware that any further SQL that you execute might not be within the same transaction. Usually, the best course of action for such cases is to simply re-throw the error, exiting the transaction function. +It's important to know that SQLite may sometimes rollback a transaction without us asking it to. This can happen either because of an [`ON CONFLICT`](https://sqlite.org/lang_conflict.html) clause, the [`RAISE()`](https://www.sqlite.org/lang_createtrigger.html) trigger function, or certain errors such as `SQLITE_FULL` or `SQLITE_BUSY`. In other words, if you catch an SQLite error *within* a transaction, you must be aware that any further SQL that you execute might not be within the same transaction. Usually, the best course of action for such cases is to simply re-throw the error, exiting the transaction function. ```js try { @@ -126,11 +126,11 @@ console.log(db.pragma('cache_size', { simple: true })); // => 32000 If execution of the PRAGMA fails, an `Error` is thrown. -It's better to use this method instead of normal [prepared statements](#preparestring---statement) when executing PRAGMA, because this method normalizes some odd behavior that may otherwise be experienced. The documentation on SQLite3 PRAGMA can be found [here](https://www.sqlite.org/pragma.html). +It's better to use this method instead of normal [prepared statements](#preparestring---statement) when executing PRAGMA, because this method normalizes some odd behavior that may otherwise be experienced. The documentation on SQLite PRAGMA can be found [here](https://www.sqlite.org/pragma.html). ### .backup(*destination*, [*options*]) -> *promise* -Initiates a [backup](https://www.sqlite.org/backup.html) of the database, returning a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) for when the backup is complete. If the backup fails, the promise will be rejected with an `Error`. You can optionally backup an attached database instead by setting the `attached` option to the name of the desired attached database. A backup file is just a regular SQLite3 database file. It can be opened by [`new Database()`](#new-databasepath-options) just like any SQLite3 database. +Initiates a [backup](https://www.sqlite.org/backup.html) of the database, returning a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) for when the backup is complete. If the backup fails, the promise will be rejected with an `Error`. You can optionally backup an attached database instead by setting the `attached` option to the name of the desired attached database. A backup file is just a regular SQLite database file. It can be opened by [`new Database()`](#new-databasepath-options) just like any SQLite database. ```js db.backup(`backup-${Date.now()}.db`) @@ -167,7 +167,7 @@ db.backup(`backup-${Date.now()}.db`, { Returns a [buffer](https://nodejs.org/api/buffer.html#buffer_class_buffer) containing the serialized contents of the database. You can optionally serialize an attached database instead by setting the `attached` option to the name of the desired attached database. -The returned buffer can be written to disk to create a regular SQLite3 database file, or it can be opened directly as an in-memory database by passing it to [`new Database()`](#new-databasepath-options). +The returned buffer can be written to disk to create a regular SQLite database file, or it can be opened directly as an in-memory database by passing it to [`new Database()`](#new-databasepath-options). ```js const buffer = db.serialize(); @@ -187,7 +187,7 @@ db.prepare('SELECT add2(?, ?)').pluck().get('foo', 'bar'); // => "foobar" db.prepare('SELECT add2(?, ?, ?)').pluck().get(12, 4, 18); // => Error: wrong number of arguments ``` -By default, user-defined functions have a strict number of arguments (determined by `function.length`). You can register multiple functions of the same name, each with a different number of arguments, causing SQLite3 to execute a different function depending on how many arguments were passed to it. If you register two functions with same name and the same number of arguments, the second registration will erase the first one. +By default, user-defined functions have a strict number of arguments (determined by `function.length`). You can register multiple functions of the same name, each with a different number of arguments, causing SQLite to execute a different function depending on how many arguments were passed to it. If you register two functions with same name and the same number of arguments, the second registration will erase the first one. If `options.varargs` is `true`, the registered function can accept any number of arguments. @@ -233,7 +233,7 @@ db.aggregate('getAverage', { db.prepare('SELECT getAverage(dollars) FROM expenses').pluck().get(); // => 20.2 ``` -As shown above, you can use arbitrary JavaScript objects as your aggregation context, as long as a valid SQLite3 value is returned by `result()` in the end. If `step()` doesn't return anything (`undefined`), the aggregate value will not be replaced (be careful of this when using functions that return `undefined` when `null` is desired). +As shown above, you can use arbitrary JavaScript objects as your aggregation context, as long as a valid SQLite value is returned by `result()` in the end. If `step()` doesn't return anything (`undefined`), the aggregate value will not be replaced (be careful of this when using functions that return `undefined` when `null` is desired). Just like regular [user-defined functions](#functionname-options-function---this), user-defined aggregates can accept multiple arguments. Furthermore, `options.varargs`, `options.directOnly`, and `options.deterministic` [are also](#functionname-options-function---this) accepted. @@ -360,7 +360,7 @@ db.exec('CREATE VIRTUAL TABLE my_data USING csv(my_data.csv)'); const allData = db.prepare('SELECT * FROM my_data').all(); ``` -The factory function will be invoked each time a corresponding `CREATE VIRTUAL TABLE` statement runs. The arguments to the factory function correspond to the module arguments passed in the `CREATE VIRTUAL TABLE` statement; always a list of arbitrary strings separated by commas. It's your responsibility to parse and interpret those module arguments. Note that SQLite3 does not allow [bound parameters](#binding-parameters) inside module arguments. +The factory function will be invoked each time a corresponding `CREATE VIRTUAL TABLE` statement runs. The arguments to the factory function correspond to the module arguments passed in the `CREATE VIRTUAL TABLE` statement; always a list of arbitrary strings separated by commas. It's your responsibility to parse and interpret those module arguments. Note that SQLite does not allow [bound parameters](#binding-parameters) inside module arguments. Just like [user-defined functions](#functionname-options-function---this) and [user-defined aggregates](#aggregatename-options---this), virtual tables support `options.directOnly`, which prevents the table from being used inside [VIEWs](https://sqlite.org/lang_createview.html), [TRIGGERs](https://sqlite.org/lang_createtrigger.html), or schema structures such as [CHECK constraints](https://www.sqlite.org/lang_createtable.html#ckconst), [DEFAULT clauses](https://www.sqlite.org/lang_createtable.html#dfltval), etc. @@ -368,9 +368,9 @@ Just like [user-defined functions](#functionname-options-function---this) and [u ### .loadExtension(*path*, [*entryPoint*]) -> *this* -Loads a compiled [SQLite3 extension](https://sqlite.org/loadext.html) and applies it to the current database connection. +Loads a compiled [SQLite extension](https://sqlite.org/loadext.html) and applies it to the current database connection. -It's your responsibility to make sure the extensions you load are compiled/linked against a version of [SQLite3](https://www.sqlite.org/) that is compatible with `better-sqlite3-multiple-ciphers`. Keep in mind that new versions of `better-sqlite3-multiple-ciphers` will periodically use newer versions of [SQLite3](https://www.sqlite.org/). You can see which version is being used [here](./compilation.md#bundled-configuration). +It's your responsibility to make sure the extensions you load are compiled/linked against a version of [SQLite](https://www.sqlite.org/) that is compatible with `better-sqlite3-multiple-ciphers`. Keep in mind that new versions of `better-sqlite3-multiple-ciphers` will periodically use newer versions of [SQLite](https://www.sqlite.org/). You can see which version is being used [here](./compilation.md#bundled-configuration). ```js db.loadExtension('./my-extensions/compress.so'); @@ -448,7 +448,7 @@ An object representing a single SQL statement. - [Statement#bind()](#bindbindparameters---this) - [Properties](#properties-1) -> NOTE: Statements are [finalized](https://www.sqlite.org/c3ref/finalize.html) when garbage collected so there is no explicit API for it. Statements are also finalized when the associated database is closed. +> NOTE: If you've used the [SQLite C API](https://www.sqlite.org/c3ref), you might except there to be a ["finalize"](https://www.sqlite.org/c3ref/finalize.html) method, but `better-sqlite3-multiple-ciphers` automatically handles this during garbage collection (or when the associated database is closed). ### .run([*...bindParameters*]) -> *object* @@ -635,11 +635,11 @@ console.log(cat.name); // => "Joey" # class *SqliteError* -Whenever an error occurs within SQLite3, a `SqliteError` object will be thrown. `SqliteError` is a subclass of `Error`. Every `SqliteError` object has a `code` property, which is a string matching one of the "extended result codes" defined [here](https://sqlite.org/rescode.html) (for example, `"SQLITE_CONSTRAINT_UNIQUE"`). +Whenever an error occurs within SQLite, a `SqliteError` object will be thrown. `SqliteError` is a subclass of `Error`. Every `SqliteError` object has a `code` property, which is a string matching one of the "extended result codes" defined [here](https://sqlite.org/rescode.html) (for example, `"SQLITE_CONSTRAINT_UNIQUE"`). -If you receive a `SqliteError`, it probably means you're using SQLite3 incorrectly. The error didn't originate in `better-sqlite3-multiple-ciphers`, so it's probably not an issue with `better-sqlite3-multiple-ciphers`. It's recommended that you learn about the meaning of the error [here](https://sqlite.org/rescode.html), and perhaps learn more about how to use SQLite3 by reading [their docs](https://sqlite.org/docs.html). +If you receive a `SqliteError`, it probably means you're using SQLite incorrectly. The error didn't originate in `better-sqlite3-multiple-ciphers`, so it's probably not an issue with `better-sqlite3-multiple-ciphers`. It's recommended that you learn about the meaning of the error [here](https://sqlite.org/rescode.html), and perhaps learn more about how to use SQLite by reading [their docs](https://sqlite.org/docs.html). -> In the unlikely scenario that SQLite3 throws an error that is not recognized by `better-sqlite3-multiple-ciphers` (this would be considered a bug in `better-sqlite3-multiple-ciphers`), the `code` property will be `"UNKNOWN_SQLITE_ERROR_NNNN"`, where `NNNN` is the numeric error code. If this happens to you, please report it as an [issue](https://github.com/m4heshd/better-sqlite3-multiple-ciphers/issues). +> In the unlikely scenario that SQLite throws an error that is not recognized by `better-sqlite3-multiple-ciphers` (this would be considered a bug in `better-sqlite3-multiple-ciphers`), the `code` property will be `"UNKNOWN_SQLITE_ERROR_NNNN"`, where `NNNN` is the numeric error code. If this happens to you, please report it as an [issue](https://github.com/m4heshd/better-sqlite3-multiple-ciphers/issues). # Binding Parameters @@ -656,7 +656,7 @@ stmt.run(['John', 'Smith', 45]); stmt.run(['John'], ['Smith', 45]); ``` -You can also use named parameters. SQLite3 provides [3 different syntaxes for named parameters](https://www.sqlite.org/lang_expr.html) (`@foo`, `:foo`, and `$foo`), all of which are supported by `better-sqlite3-multiple-ciphers`. +You can also use named parameters. SQLite provides [3 different syntaxes for named parameters](https://www.sqlite.org/lang_expr.html) (`@foo`, `:foo`, and `$foo`), all of which are supported by `better-sqlite3-multiple-ciphers`. ```js // The following are equivalent. @@ -679,12 +679,12 @@ const stmt = db.prepare('INSERT INTO people VALUES (@name, @name, ?)'); stmt.run(45, { name: 'Henry' }); ``` -Here is how `better-sqlite3` converts values between SQLite3 and JavaScript: +Here is how `better-sqlite3-multiple-ciphers` converts values between SQLite and JavaScript: -|SQLite3|JavaScript| +|SQLite|JavaScript| |---|---| |`NULL`|`null`| |`REAL`|`number`| -|`INTEGER`|`number` [or `BigInt`](https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/integer.md#the-bigint-primitive-type)| +|`INTEGER`|`number` [or `BigInt`](https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md#the-bigint-primitive-type)| |`TEXT`|`string`| |`BLOB`|[`Buffer`](https://nodejs.org/api/buffer.html#buffer_class_buffer)| diff --git a/docs/compilation.md b/docs/compilation.md index f49de325..1c233a9a 100644 --- a/docs/compilation.md +++ b/docs/compilation.md @@ -1,6 +1,6 @@ # Custom configuration -If you want to use a customized version of [SQLite3](https://www.sqlite.org) with `better-sqlite3-multiple-ciphers`, you can do so by specifying the directory of your [custom amalgamation](https://www.sqlite.org/amalgamation.html) during installation. +If you want to use a customized version of [SQLite](https://www.sqlite.org) with `better-sqlite3-multiple-ciphers`, you can do so by specifying the directory of your [custom amalgamation](https://www.sqlite.org/amalgamation.html) during installation. ```bash npm install better-sqlite3-multiple-ciphers --build-from-source --sqlite3=/path/to/sqlite-amalgamation @@ -30,7 +30,7 @@ Your amalgamation directory must contain `sqlite3.c` and `sqlite3.h`. Any desire If you're creating a package that relies on a custom build of `better-sqlite3-multiple-ciphers`, you can follow these steps to get started. -1. Download the SQLite3 source code from [their website](https://sqlite.com/download.html) (e.g., `sqlite-amalgamation-1234567.zip`) +1. Download the SQLite source code from [their website](https://sqlite.com/download.html) (e.g., `sqlite-amalgamation-1234567.zip`) 2. Unzip the compressed archive 3. Move the `sqlite3.c` and `sqlite3.h` files to your project folder 4. Add a `preinstall` script to your `package.json`, like the one shown above @@ -39,11 +39,11 @@ If you're creating a package that relies on a custom build of `better-sqlite3-mu 8. Make sure to remove `better-sqlite3-multiple-ciphers` from your `dependencies` 9. Run `npm install` in your project folder -If you're using a SQLite3 encryption extension that is a drop-in replacement for SQLite3 (such as [SEE](https://www.sqlite.org/see/doc/release/www/readme.wiki) or [sqleet](https://github.com/resilar/sqleet)), then simply replace `sqlite3.c` and `sqlite3.h` with the source files of your encryption extension. +If you're using a SQLite encryption extension that is a drop-in replacement for SQLite (such as [SEE](https://www.sqlite.org/see/doc/release/www/readme.wiki) or [sqleet](https://github.com/resilar/sqleet)), then simply replace `sqlite3.c` and `sqlite3.h` with the source files of your encryption extension. # Bundled configuration -By default, this distribution currently uses SQLite3 **version 3.48.0** with the following [compilation options](https://www.sqlite.org/compile.html): +By default, this distribution currently uses SQLite **version 3.48.0** with the following [compilation options](https://www.sqlite.org/compile.html): ``` HAVE_INT16_T=1 diff --git a/docs/integer.md b/docs/integer.md index da62bc58..56b728a0 100644 --- a/docs/integer.md +++ b/docs/integer.md @@ -1,6 +1,6 @@ # The `BigInt` primitive type -SQLite3 can store data in 64-bit signed integers, which are too big for JavaScript's [number format](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) to fully represent. To support this data type, `better-sqlite3` is fully compatible with [BigInts](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). +SQLite can store data in 64-bit signed integers, which are too big for JavaScript's [number format](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) to fully represent. To support this data type, `better-sqlite3-multiple-ciphers` is fully compatible with [BigInts](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). ```js const big = BigInt('1152735103331642317'); diff --git a/docs/performance.md b/docs/performance.md index 9babdafd..df133d15 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -1,6 +1,6 @@ # Performance -Concurrently reading and writing from an SQLite3 database can be very slow in some cases. Since concurrency is usually very important in web applications, it's recommended to turn on [WAL mode](https://www.sqlite.org/wal.html) to greatly increase overall performance. +Concurrently reading and writing from an SQLite database can be very slow in some cases. Since concurrency is usually very important in web applications, it's recommended to turn on [WAL mode](https://www.sqlite.org/wal.html) to greatly increase overall performance. ```js db.pragma('journal_mode = WAL'); @@ -16,7 +16,7 @@ However, you trade those disadvantages for extremely fast performance in most we ## Checkpoint starvation -Checkpoint starvation is when SQLite3 is unable to recycle the [WAL file](https://www.sqlite.org/wal.html) due to everlasting concurrent reads to the database. If this happens, the WAL file will grow without bound, leading to unacceptable amounts of disk usage and deteriorating performance. +Checkpoint starvation is when SQLite is unable to recycle the [WAL file](https://www.sqlite.org/wal.html) due to everlasting concurrent reads to the database. If this happens, the WAL file will grow without bound, leading to unacceptable amounts of disk usage and deteriorating performance. If you don't access the database from multiple processes or threads simultaneously, you'll never encounter this issue. @@ -34,6 +34,6 @@ setInterval(fs.stat.bind(null, 'foobar.db-wal', (err, stat) => { ## A note about durability -This distribution of SQLite3 uses the `SQLITE_DEFAULT_WAL_SYNCHRONOUS=1` [compile-time option](https://sqlite.org/compile.html#default_wal_synchronous), which makes databases in WAL mode default to the ["NORMAL" synchronous setting](https://sqlite.org/pragma.html#pragma_synchronous). This allows applications to achieve extreme performance, but introduces a slight loss of [durability](https://en.wikipedia.org/wiki/Durability_(database_systems)) while in WAL mode. +This distribution of SQLite uses the `SQLITE_DEFAULT_WAL_SYNCHRONOUS=1` [compile-time option](https://sqlite.org/compile.html#default_wal_synchronous), which makes databases in WAL mode default to the ["NORMAL" synchronous setting](https://sqlite.org/pragma.html#pragma_synchronous). This allows applications to achieve extreme performance, but introduces a slight loss of [durability](https://en.wikipedia.org/wiki/Durability_(database_systems)) while in WAL mode. You can override this setting by running `db.pragma('synchronous = FULL')`. diff --git a/docs/threads.md b/docs/threads.md index a32d957a..8019246d 100644 --- a/docs/threads.md +++ b/docs/threads.md @@ -1,6 +1,6 @@ # Worker threads -For most applications, `better-sqlite3` is fast enough to use in the main thread without blocking for a noticeable amount of time. However, if you need to perform very slow queries, you have the option of using [worker threads](https://nodejs.org/api/worker_threads.html) to keep things running smoothly. Below is an example of using a thread pool to perform queries in the background. +For most applications, `better-sqlite3-multiple-ciphers` is fast enough to use in the main thread without blocking for a noticeable amount of time. However, if you need to perform very slow queries, you have the option of using [worker threads](https://nodejs.org/api/worker_threads.html) to keep things running smoothly. Below is an example of using a thread pool to perform queries in the background. ### worker.js diff --git a/docs/tips.md b/docs/tips.md index f9d91101..98fb11da 100644 --- a/docs/tips.md +++ b/docs/tips.md @@ -1,13 +1,13 @@ -# Helpful tips for SQLite3 +# Helpful tips for SQLite ## Creating good tables It's a good idea to use `INTEGER PRIMARY KEY AUTOINCREMENT` as one of the columns in a table. This ensures two things: -- `INTEGER PRIMARY KEY`: improved performance by reusing SQLite3's built-in `rowid` column. +- `INTEGER PRIMARY KEY`: improved performance by reusing SQLite's built-in `rowid` column. - `AUTOINCREMENT`: no future row will have the same ID as an old one that was deleted. This can prevent potential bugs and security breaches. -If you don't use `INTEGER PRIMARY KEY`, then you *must* use `NOT NULL` in all of your your primary key columns. Otherwise you'll be victim to an SQLite3 bug that allows primary keys to be `NULL`. +If you don't use `INTEGER PRIMARY KEY`, then you *must* use `NOT NULL` in all of your your primary key columns. Otherwise you'll be victim to an SQLite bug that allows primary keys to be `NULL`. Any column with `INTEGER PRIMARY KEY` will automatically increment when setting its value to `NULL`. But without `AUTOINCREMENT`, the behavior only ensures uniqueness from currently existing rows. diff --git a/docs/unsafe.md b/docs/unsafe.md index 1abb23f7..63df4984 100644 --- a/docs/unsafe.md +++ b/docs/unsafe.md @@ -1,6 +1,6 @@ # Unsafe mode -By default, `better-sqlite3` prevents you from doing things that might corrupt your database or cause undefined behavior. Such unsafe operations include: +By default, `better-sqlite3-multiple-ciphers` prevents you from doing things that might corrupt your database or cause undefined behavior. Such unsafe operations include: - Anything blocked by [`SQLITE_DBCONFIG_DEFENSIVE`](https://www.sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive) - Mutating the database while [iterating](https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/api.md#iteratebindparameters---iterator) through a query's result set @@ -13,4 +13,4 @@ db.unsafeMode(true); // Unsafe mode ON db.unsafeMode(false); // Unsafe mode OFF ``` -Unsafe mode can be toggled at any time, and independently for each database connection. While toggled on, `better-sqlite3` will not prevent you from performing the dangerous operations listed above. +Unsafe mode can be toggled at any time, and independently for each database connection. While toggled on, `better-sqlite3-multiple-ciphers` will not prevent you from performing the dangerous operations listed above.