### Install Beta Version Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/README.md Install the beta version of the better-sqlite3-multiple-ciphers package using npm. ```bash npm install better-sqlite3-multiple-ciphers@beta ``` -------------------------------- ### Running the Benchmark Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/benchmark.md Instructions to clone the repository, install dependencies, and run the benchmark script. ```bash git clone https://github.com/m4heshd/better-sqlite3-multiple-ciphers.git cd better-sqlite3-multiple-ciphers npm install # if you're doing this as the root user, --unsafe-perm is required node benchmark ``` -------------------------------- ### Install Stable Version Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/README.md Install the stable version of the better-sqlite3-multiple-ciphers package using npm. ```bash npm install better-sqlite3-multiple-ciphers ``` -------------------------------- ### Install with Custom SQLite Amalgamation Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/compilation.md Use this command to install better-sqlite3-multiple-ciphers from a custom SQLite amalgamation source. Ensure the --sqlite3 flag points to your amalgamation directory. ```bash npm install better-sqlite3-multiple-ciphers --build-from-source --sqlite3=/path/to/sqlite-amalgamation ``` -------------------------------- ### Add preinstall Script for Custom Compilation Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/compilation.md Recommended for projects relying on better-sqlite3-multiple-ciphers. This ensures the custom build flags are applied during installation. The --sqlite3 flag uses a relative path to the amalgamation directory. ```json { "scripts": { "preinstall": "npm install better-sqlite3-multiple-ciphers@'^7.0.0' --no-save --build-from-source --sqlite3=\"$(pwd)/sqlite-amalgamation\"" } } ``` -------------------------------- ### Register a Simple Aggregate Function Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Register a custom aggregate function that sums values. The `start` option initializes the total, and `step` accumulates values for each row. ```javascript db.aggregate('addAll', { start: 0, step: (total, nextValue) => total + nextValue, }); db.prepare('SELECT addAll(dollars) FROM expenses').pluck().get(); // => 92 ``` -------------------------------- ### Register an Aggregate Function for Window Functions Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Register an aggregate function that supports window functions by including an `inverse` function to remove values from the window. This example calculates a running total within partitions. ```javascript db.aggregate('addAll', { start: 0, step: (total, nextValue) => total + nextValue, inverse: (total, droppedValue) => total - droppedValue, result: total => Math.round(total), }); db.prepare(` SELECT timestamp, dollars, addAll(dollars) OVER day as dayTotal FROM expenses WINDOW day AS (PARTITION BY date(timestamp)) ORDER BY timestamp `).all(); ``` -------------------------------- ### Register a Varargs User-Defined Function Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Register a function that accepts a variable number of arguments. This example also sets the function as deterministic, which can improve performance. ```javascript db.function('void', { deterministic: true, varargs: true }, () => {}); db.prepare("SELECT void() περιστρεφόμενο").pluck().get(); // => null db.prepare("SELECT void(?, ?)").pluck().get(55, 19); // => null ``` -------------------------------- ### Register an Aggregate Function with Result Transformation Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Register an aggregate function to calculate the average. It uses `start` to initialize an array, `step` to collect values, and `result` to compute the final average. ```javascript db.aggregate('getAverage', { start: () => [], step: (array, nextValue) => { array.push(nextValue); }, result: array => array.reduce(sum) / array.length, }); db.prepare('SELECT getAverage(dollars) FROM expenses').pluck().get(); // => 20.2 ``` -------------------------------- ### Execute INSERT statement and get info Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use .run() to execute statements that modify data (INSERT, UPDATE, DELETE). It returns an info object with changes count and last inserted row ID. ```javascript const stmt = db.prepare('INSERT INTO cats (name, age) VALUES (?, ?)'); const info = stmt.run('Joey', 2); console.log(info.changes); // => 1 ``` -------------------------------- ### Execute SELECT statement and get all rows Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use .all() to execute statements that retrieve data and fetch all matching rows. Returns an array of row objects, or an empty array if no data is found. ```javascript const stmt = db.prepare('SELECT * FROM cats WHERE name = ?'); const cats = stmt.all('Joey'); console.log(cats.length); // => 1 ``` -------------------------------- ### Execute SELECT statement and get one row Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use .get() to execute statements that retrieve data and fetch only the first matching row. Returns an object with column names as keys, or undefined if no data is found. ```javascript const stmt = db.prepare('SELECT age FROM cats WHERE name = ?'); const cat = stmt.get('Joey'); console.log(cat.age); // => 2 ``` -------------------------------- ### .aggregate(*name*, *options*) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Registers a user-defined SQL aggregate function. This function can be used in SQL statements to perform aggregations over rows. It supports custom start, step, result, and inverse functions. ```APIDOC ## .aggregate(*name*, *options*) -> *this* Registers a user-defined [aggregate function](https://sqlite.org/lang_aggfunc.html). The `step()` function will be invoked once for each row passed to the aggregate, using its return value as the new aggregate value. This works similarly to [Array#reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce). If `options.start` is a function, it will be invoked at the beginning of each aggregate, using its return value as the initial aggregate value. If `options.start` is *not* a function, it will be used as the initial aggregate value *as-is*. If not provided, the initial aggregate value will be `null`. You can also provide a `result()` function to transform the final aggregate value. 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. If you provide an `inverse()` function, the aggregate can be used as a [window function](https://www.sqlite.org/windowfunctions.html). Where `step()` is used to add a row to the current window, `inverse()` is used to remove a row from the current window. When using window functions, `result()` may be invoked multiple times. ### Example Usage: ```js db.aggregate('addAll', { start: 0, step: (total, nextValue) => total + nextValue, }); db.prepare('SELECT addAll(dollars) FROM expenses').pluck().get(); // => 92 db.aggregate('getAverage', { start: () => [], step: (array, nextValue) => { array.push(nextValue); }, result: array => array.reduce(sum) / array.length, }); db.prepare('SELECT getAverage(dollars) FROM expenses').pluck().get(); // => 20.2 db.aggregate('addAll', { start: 0, step: (total, nextValue) => total + nextValue, inverse: (total, droppedValue) => total - droppedValue, result: total => Math.round(total), }); db.prepare(` SELECT timestamp, dollars, addAll(dollars) OVER day as dayTotal FROM expenses WINDOW day AS (PARTITION BY date(timestamp)) ORDER BY timestamp `).all(); ``` ``` -------------------------------- ### Get Column Information with Raw Mode Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md The `.columns()` method retrieves metadata about the result columns, primarily used in conjunction with `.raw()`. It returns an array of objects, each detailing a column's name, originating table, database, and type. It's recommended to call `.columns()` after executing the statement to ensure accurate schema reflection. ```javascript function* toRows(stmt) { yield stmt.columns().map(column => column.name); yield* stmt.raw().iterate(); } function writeToCSV(filename, stmt) { return new Promise((resolve, reject) => { const stream = fs.createWriteStream(filename); for (const row of toRows(stmt)) { stream.write(row.join(',') + '\n'); } stream.on('error', reject); stream.end(resolve); }); } ``` -------------------------------- ### Creating and Using BigInts Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Demonstrates how to create BigInt literals and perform basic operations like string conversion and type checking. ```javascript const big = BigInt('1152735103331642317'); big === 1152735103331642317n; // returns true big.toString(); // returns "1152735103331642317" typeof big; // returns "bigint" ``` -------------------------------- ### .run([*...bindParameters*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a prepared statement and returns an info object with changes made. Supports bind parameters. ```APIDOC ## .run([*...bindParameters*]) ### Description Executes the prepared statement. When execution completes it returns an `info` object describing any changes made. The `info` object has two properties: `changes` (the total number of rows that were inserted, updated, or deleted) and `lastInsertRowid` (the rowid of the last row inserted). If execution fails, an `Error` is thrown. Bind parameters can be specified. ### Method `run` ### Parameters #### Bind Parameters `*...bindParameters` - Variable number of parameters to bind to the statement. ### Request Example ```js const stmt = db.prepare('INSERT INTO cats (name, age) VALUES (?, ?)'); const info = stmt.run('Joey', 2); console.log(info.changes); // => 1 ``` ### Response #### Success Response - `info` (object) - An object containing information about the changes made. - `changes` (number) - The total number of rows inserted, updated, or deleted. - `lastInsertRowid` (number) - The rowid of the last row inserted. #### Response Example ```json { "changes": 1, "lastInsertRowid": 123 } ``` ``` -------------------------------- ### Initiate Database Backup Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Initiates a backup of the database to a file. The promise resolves when the backup is complete or rejects if it fails. You can optionally backup attached databases. ```javascript db.backup(`backup-${Date.now()}.db`) .then(() => { console.log('backup complete!'); }) .catch((err) => { console.log('backup failed:', err); }); ``` -------------------------------- ### Close Database Connection Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Closes the database connection. No further statements can be created or executed after this method is called. This example shows how to ensure the connection is closed on process exit or specific signals. ```javascript process.on('exit', () => db.close()); process.on('SIGHUP', () => process.exit(128 + 1)); process.on('SIGINT', () => process.exit(128 + 2)); process.on('SIGTERM', () => process.exit(128 + 15)); ``` -------------------------------- ### .backup(*destination*, [*options*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Initiates a backup of the database. The backup can be an attached database by specifying the 'attached' option. Progress can be monitored via the 'progress' callback. ```APIDOC ## .backup(*destination*, [*options*]) ### Description Initiates a backup of the database, returning a promise 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. ### Method Asynchronous function call ### Parameters #### Path Parameters - **destination** (string) - Required - The file path for the backup. - **options** (object) - Optional - Configuration options for the backup. - **attached** (string) - Optional - The name of the attached database to backup. - **progress** (function) - Optional - A callback function to monitor backup progress. - **totalPages** (number) - The total number of pages in the source database. - **remainingPages** (number) - The number of pages remaining to be transferred. - The function can return a number to specify the number of pages to transfer per cycle. ### Request Example ```js db.backup(`backup-${Date.now()}.db`) .then(() => { console.log('backup complete!'); }) .catch((err) => { console.log('backup failed:', err); }); ``` ### Response #### Success Response (Promise resolves) - **totalPages** (number) - The total number of pages in the database. - **remainingPages** (number) - 0, indicating the backup is complete. #### Response Example ```js { "totalPages": 1000, "remainingPages": 0 } ``` ### Error Handling - The promise will be rejected with an `Error` if the backup fails. - If the `progress` callback throws an exception, the backup will be aborted. - If the parent database connection is closed, all pending backups will be automatically aborted. ``` -------------------------------- ### Create a new Database connection Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Opens a new database connection. Creates the file if it doesn't exist. Supports in-memory and temporary databases. Options can configure read-only mode, file existence checks, timeouts, verbose logging, and native binding paths. ```javascript const Database = require('better-sqlite3-multiple-ciphers'); const db = new Database('foobar.db', { verbose: console.log }); ``` -------------------------------- ### Execute SELECT statement and iterate over rows Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use .iterate() to execute statements that retrieve data and get an iterator for rows. This is useful for processing large result sets one row at a time. ```javascript const stmt = db.prepare('SELECT * FROM cats'); for (const cat of stmt.iterate()) { if (cat.name === 'Joey') { console.log('found him!'); break; } } ``` -------------------------------- ### .loadExtension(*path*, [*entryPoint*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Loads a compiled SQLite extension and applies it to the current database connection. Ensure extensions are compiled against a compatible SQLite version. ```APIDOC ## .loadExtension(*path*, [*entryPoint*]) ### Description 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 [SQLite](https://www.sqlite.org/) that is compatible with `better-sqlite3-multiple-ciphers`. ### Method ```js db.loadExtension('./my-extensions/compress.so'); ``` ``` -------------------------------- ### Virtual Tables with BigInt Support Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Demonstrates how to create virtual tables where columns can handle BigInt values, including defining the schema and implementing the rows generator function. ```javascript db.table('sequence', { safeIntegers: true, columns: ['value'], parameters: ['length', 'start'], rows: function* (length, start = 0n) { const end = start + length; for (let n = start; n < end; ++n) { yield { value: n }; } }, }); ``` -------------------------------- ### Database#prepare() Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Creates a new prepared Statement from the given SQL string, allowing for efficient execution of parameterized queries. ```APIDOC ## Database#prepare(*string*) ### Description Creates a new prepared [`Statement`](#class-statement) from the given SQL string. ### Parameters #### Path Parameters - **string** (string) - Required - The SQL string to prepare. ### Response - **Statement** - A prepared statement object. ### Request Example ```js const stmt = db.prepare('SELECT name, age FROM cats'); ``` ``` -------------------------------- ### Monitor Database Backup Progress Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Initiates a database backup and allows monitoring of its progress using a callback function. The callback can control the transfer rate by returning a number of pages to transfer per cycle. Returning 0 pauses the backup. ```javascript let paused = false; db.backup(`backup-${Date.now()}.db`, { progress({ totalPages: t, remainingPages: r }) { console.log(`progress: ${((t - r) / t * 100).toFixed(1)}%`); return paused ? 0 : 200; } }); ``` -------------------------------- ### Configuring Default Safe Integers Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Demonstrates how to configure the database to return BigInts by default for all integer values retrieved from the database, or revert to standard JavaScript numbers. ```javascript db.defaultSafeIntegers(); // BigInts by default db.defaultSafeIntegers(true); // BigInts by default db.defaultSafeIntegers(false); // Numbers by default ``` -------------------------------- ### Benchmark Results Summary Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/benchmark.md A summary of benchmark results comparing better-sqlite3-multiple-ciphers and node-sqlite3 for different operations. All benchmarks are executed in WAL mode. ```text --- --- reading rows individually --- better-sqlite3-multiple-ciphers x 313,899 ops/sec ±0.13% node-sqlite3 x 26,780 ops/sec ±2.9% --- reading 100 rows into an array --- better-sqlite3-multiple-ciphers x 8,508 ops/sec ±0.27% node-sqlite3 x 2,930 ops/sec ±0.37% --- iterating over 100 rows --- better-sqlite3-multiple-ciphers x 6,532 ops/sec ±0.32% node-sqlite3 x 268 ops/sec ±3.4% --- inserting rows individually --- better-sqlite3-multiple-ciphers x 62,554 ops/sec ±7.33% node-sqlite3 x 22,637 ops/sec ±4.37% --- inserting 100 rows in a single transaction --- better-sqlite3-multiple-ciphers x 4,141 ops/sec ±4.57% node-sqlite3 x 265 ops/sec ±4.87% --- > All benchmarks are executed in [WAL mode](./performance.md). ``` -------------------------------- ### .all([*...bindParameters*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a prepared statement and retrieves all matching rows as an array. Supports bind parameters. Returns an empty array if no rows are found. ```APIDOC ## .all([*...bindParameters*]) ### Description Similar to `.get()`, but retrieves all matching rows. The return value is an array of row objects. If no rows are found, the array will be empty. If execution fails, an `Error` is thrown. Bind parameters can be specified. ### Method `all` ### Parameters #### Bind Parameters `*...bindParameters` - Variable number of parameters to bind to the statement. ### Request Example ```js const stmt = db.prepare('SELECT * FROM cats WHERE name = ?'); const cats = stmt.all('Joey'); console.log(cats.length); // => 1 ``` ### Response #### Success Response - `array of rows` (array) - An array of row objects. Each object represents a row retrieved by the query. #### Response Example ```json [ { "name": "Joey", "age": 2 } ] ``` ``` -------------------------------- ### new Database() Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Creates a new database connection. Supports in-memory, temporary, and file-based databases with various configuration options. ```APIDOC ## new Database(*path*, [*options*]) ### Description Creates a new database connection. If the database file does not exist, it is created. This happens synchronously, which means you can start executing queries right away. You can create an [in-memory database](https://www.sqlite.org/inmemorydb.html) by passing `":memory:"` as the first argument. You can create a temporary database by passing an empty string (or by omitting all arguments). > In-memory databases can also be created by passing a buffer returned by [`.serialize()`](#serializeoptions---buffer), instead of passing a string as the first argument. ### Parameters #### Path Parameter - **path** (string | Buffer) - Required - The path to the database file, ":memory:" for an in-memory database, or an empty string for a temporary database. Can also be a buffer from `.serialize()`. #### Options - **options.readonly** (boolean) - Optional - Open the database connection in readonly mode (default: `false`). - **options.fileMustExist** (boolean) - Optional - If the database does not exist, an `Error` will be thrown instead of creating a new file. This option is ignored for in-memory, temporary, or readonly database connections (default: `false`). - **options.timeout** (number) - Optional - The number of milliseconds to wait when executing queries on a locked database, before throwing a `SQLITE_BUSY` error (default: `5000`). - **options.verbose** (function) - Optional - Provide a function that gets called with every SQL string executed by the database connection (default: `null`). - **options.nativeBinding** (string) - Optional - Path to the native C++ addon (`better_sqlite3.node`) if it cannot be located automatically. ### Request Example ```js const Database = require('better-sqlite3-multiple-ciphers'); const db = new Database('foobar.db', { verbose: console.log }); ``` ``` -------------------------------- ### Set Synchronous Mode to FULL Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/performance.md Override the default 'NORMAL' synchronous setting for WAL mode to 'FULL' for increased durability, at the cost of some performance. This ensures data is written to disk before transactions are reported as committed. ```javascript db.pragma('synchronous = FULL'); ``` -------------------------------- ### Enable WAL Mode Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/performance.md Turn on WAL mode to greatly increase overall performance for concurrent read/write operations. This is recommended for most web applications. ```javascript db.pragma('journal_mode = WAL'); ``` -------------------------------- ### Prepare a SQL statement Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Creates a new prepared statement from a SQL string for execution. ```javascript const stmt = db.prepare('SELECT name, age FROM cats'); ``` -------------------------------- ### User-Defined Aggregates with BigInt Support Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Shows how to define user-defined aggregate functions that can process BigInt values, including setting an initial BigInt value and defining the aggregation step. ```javascript db.aggregate('addInts', { safeIntegers: true, start: 0n, step: (total, nextValue) => total + nextValue, }); ``` -------------------------------- ### User-Defined Functions with BigInt Support Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Illustrates how user-defined functions can receive BigInt arguments and how to explicitly enable safe integer handling for them. ```javascript db.function('isInt', { safeIntegers: true }, (value) => { return String(typeof value === 'bigint'); }); db.prepare('SELECT isInt(?)').pluck().get(10); // => "false" db.prepare('SELECT isInt(?)').pluck().get(10n); // => "true" ``` -------------------------------- ### .get([*...bindParameters*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a prepared statement and returns the first row retrieved. Supports bind parameters. Returns undefined if no data is found. ```APIDOC ## .get([*...bindParameters*]) ### Description Executes the prepared statement. When execution completes it returns an object that represents the first row retrieved by the query. The object's keys represent column names. If the statement was successful but found no data, `undefined` is returned. If execution fails, an `Error` is thrown. Bind parameters can be specified. ### Method `get` ### Parameters #### Bind Parameters `*...bindParameters` - Variable number of parameters to bind to the statement. ### Request Example ```js const stmt = db.prepare('SELECT age FROM cats WHERE name = ?'); const cat = stmt.get('Joey'); console.log(cat.age); // => 2 ``` ### Response #### Success Response - `row` (object | undefined) - An object representing the first row, or undefined if no rows are found. #### Response Example ```json { "age": 2 } ``` ``` -------------------------------- ### Basic Database Usage Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/README.md Connect to a SQLite database and perform a basic query using the commonJS module notation. Ensure 'options' are defined if needed. ```javascript const db = require('better-sqlite3-multiple-ciphers')('foobar.db', options); const row = db.prepare('SELECT * FROM users WHERE id = ?').get(userId); console.log(row.firstName, row.lastName, row.email); ``` -------------------------------- ### .serialize([*options*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Returns a buffer containing the serialized contents of the database. An attached database can be serialized by setting the 'attached' option. ```APIDOC ## .serialize([*options*]) ### Description Returns a 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. ### Method Synchronous function call ### Parameters #### Path Parameters - **options** (object) - Optional - Configuration options for serialization. - **attached** (string) - Optional - The name of the attached database to serialize. ### Request Example ```js const buffer = db.serialize(); db.close(); db = new Database(buffer); ``` ### Response #### Success Response (Buffer) - Returns a Buffer object containing the serialized database content. #### Response Example ```js // Example of a Buffer object (content will vary) ``` ``` -------------------------------- ### Set Journal Mode to WAL Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/README.md Configure the database to use the Write-Ahead Logging (WAL) mode for improved performance. This is generally recommended. ```javascript db.pragma('journal_mode = WAL'); ``` -------------------------------- ### Execute Raw SQL String Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a given SQL string, which can contain multiple statements. This method is less performant and secure than prepared statements and should primarily be used for executing SQL from external sources like files. Manual rollback is required if an error occurs. ```javascript const migration = fs.readFileSync('migrate-schema.sql', 'utf8'); db.exec(migration); ``` -------------------------------- ### Properties Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Exposes properties of the prepared statement object. ```APIDOC ## Properties ### .database -> _object_ - **Description**: The parent database object. ### .source -> _string_ - **Description**: The source string that was used to create the prepared statement. ### .reader -> _boolean_ - **Description**: Whether the prepared statement returns data. ### .readonly -> _boolean_ - **Description**: Whether the prepared statement is readonly, meaning it does not mutate the database (note that [SQL functions might still change the database indirectly](https://www.sqlite.org/c3ref/stmt_readonly.html) as a side effect, even if the `.readonly` property is `true`). ### .busy -> _boolean_ - **Description**: Whether the prepared statement is busy executing a query via the [`.iterate()`](#iteratebindparameters---iterator) method. ``` -------------------------------- ### Register Filesystem Directory Virtual Table Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Registers a virtual table named 'filesystem_directory' that exposes files and their data from the current working directory. Requires the 'fs' module. ```javascript const fs = require('fs'); db.table('filesystem_directory', { columns: ['filename', 'data'], rows: function* () { for (const filename of fs.readdirSync(process.cwd())) { const data = fs.readFileSync(filename); yield { filename, data }; } }, }); const files = db.prepare('SELECT * FROM filesystem_directory').all(); // => [{ filename, data }, { filename, data }] ``` -------------------------------- ### .key(*Buffer*) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Decrypts or encrypts the database using a provided binary key. This method is a direct wrapper around the underlying `sqlite3_key()` function and should be used when the key is a binary byte array. ```APIDOC ## .key(*Buffer*) ### Description Decrypts or encrypts the database using provided key. Use this instead of `PRAGMA key` when your key is a binary byte array which could lead to a string which is not accepted by `PRAGMA key`. It directly uses the underlying [`sqlite3_key()`](https://utelle.github.io/SQLite3MultipleCiphers/docs/configuration/config_capi/#config_key) function. It returns the result of sqlite3_key or throws an error. ### Method ```js db.pragma(`cipher='aes256cbc'`); db.key(Buffer.from('password')); ``` ``` -------------------------------- ### .iterate([*...bindParameters*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a prepared statement and returns an iterator to retrieve rows one by one. Supports bind parameters. ```APIDOC ## .iterate([*...bindParameters*]) ### Description Similar to `.all()`, but returns an iterator to retrieve rows one by one. If execution fails, an `Error` is thrown and the iterator is closed. Bind parameters can be specified. ### Method `iterate` ### Parameters #### Bind Parameters `*...bindParameters` - Variable number of parameters to bind to the statement. ### Request Example ```js const stmt = db.prepare('SELECT * FROM cats'); for (const cat of stmt.iterate()) { if (cat.name === 'Joey') { console.log('found him!'); break; } } ``` ### Response #### Success Response - `iterator` (iterator) - An iterator yielding row objects. #### Response Example ```js // Example usage within a for...of loop ``` ``` -------------------------------- ### .pragma(*string*, [*options*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes a PRAGMA statement and returns its result. The `simple` option can be used to retrieve only the first column of the first row. ```APIDOC ## .pragma(*string*, [*options*]) ### Description Executes the given PRAGMA and returns its result. By default, the return value will be an array of result rows. Each row is represented by an object whose keys correspond to column names. The `simple` option can be used to retrieve only the first column of the first row. ### Method `db.pragma(pragmaString, [options])` ### Parameters #### Path Parameters - **pragmaString** (string) - Required - The PRAGMA statement to execute (e.g., `'cache_size = 32000'`, `'cache_size'`). - **options** (object) - Optional - Configuration options. - **simple** (boolean) - Optional - If `true`, returns only the first column of the first row. ### Request Example ```js db.pragma('cache_size = 32000'); console.log(db.pragma('cache_size', { simple: true })); // => 32000 ``` ### Response #### Success Response - **results** (array of objects | any) - An array of result rows (objects) or a single value if `simple: true`. #### Response Example ```js // For db.pragma('cache_size', { simple: true }) 32000 // For a PRAGMA returning multiple columns/rows [ { column1: 'value1', column2: 'value2' }, { column1: 'value3', column2: 'value4' } ] ``` ### Error Handling If execution of the PRAGMA fails, an `Error` is thrown. ``` -------------------------------- ### Define Compile Time Options in sqlite3.c Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/compilation.md Place these preprocessor directives at the top of your custom sqlite3.c file to enable specific SQLite features or modify its behavior. These options are applied during the build process. ```c // These go at the top of the file #define SQLITE_ENABLE_FTS5 1 #define SQLITE_DEFAULT_CACHE_SIZE 16000 // ... the original content of the file remains below ``` -------------------------------- ### Handle Checkpoint Starvation Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/performance.md Periodically check the size of the WAL file and trigger a checkpoint if it grows too large to prevent unbounded growth and performance degradation. This is useful when accessing the database from multiple processes or threads simultaneously. ```javascript setInterval(fs.stat.bind(null, 'foobar.db-wal', (err, stat) => { if (err) { if (err.code !== 'ENOENT') throw err; } else if (stat.size > someUnacceptableSize) { db.pragma('wal_checkpoint(RESTART)'); } }), 5000).unref(); ``` -------------------------------- ### .rekey(*Buffer*) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Encrypts or re-encrypts the database using a provided binary key. This method is a direct wrapper around the underlying `sqlite3_rekey()` function and is used when the key is a binary byte array. If the database is already encrypted, it must be decrypted first. ```APIDOC ## .rekey(*Buffer*) ### Description Encrypts or re-encrypts the database using provided key. Use this instead of `PRAGMA rekey` when your key is a binary byte array which could lead to a string which is not accepted by `PRAGMA rekey`. It directly uses the underlying [`sqlite3_rekey()`](https://utelle.github.io/SQLite3MultipleCiphers/docs/configuration/config_capi/#functions-sqlite3_rekey-and-sqlite3_rekey_v2) function. If the database is already encrypted, it requires you to decrypt the database first. It returns the result of sqlite3_rekey or throws an error. ### Method ```js db.pragma(`cipher='aes256cbc'`); db.key(Buffer.from('oldpassword')); db.rekey(Buffer.from('newpassword')); ``` ``` -------------------------------- ### .exec(*string*) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Executes the given SQL string. This method can execute multiple SQL statements and is recommended for executing SQL from external sources like files. Note that it performs worse and is less safe than prepared statements. ```APIDOC ## .exec(*string*) ### Description Executes the given SQL string. Unlike [prepared statements](#preparestring---statement), this can execute strings that contain multiple SQL statements. This function performs worse and is less safe than using [prepared statements](#preparestring---statement). You should only use this method when you need to execute SQL from an external source (usually a file). If an error occurs, execution stops and further statements are not executed. You must rollback changes manually. ### Method ```js const migration = fs.readFileSync('migrate-schema.sql', 'utf8'); db.exec(migration); ``` ``` -------------------------------- ### Binding BigInts to Statements Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/integer.md Shows how to bind BigInt values to SQL statements for SELECT, INSERT, and other operations. It also illustrates the error handling for BigInts exceeding the 64-bit signed integer limit. ```javascript db.prepare("SELECT * FROM users WHERE id=?").get(BigInt('1152735103331642317')); db.prepare("INSERT INTO users (id) VALUES (?)").run(BigInt('1152735103331642317')); db.prepare("SELECT ?").get(2n ** 63n - 1n); // returns successfully db.prepare("SELECT ?").get(2n ** 63n); // throws a RangeError ``` -------------------------------- ### Serialize Database to Buffer Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Serializes the entire database content into a Buffer. This buffer can be saved to a file or used to open a new in-memory database. ```javascript const buffer = db.serialize(); db.close(); db = new Database(buffer); ``` -------------------------------- ### .columns() Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md This method is primarily used in conjunction with raw mode. It returns an array of objects, where each object describes a result column of the prepared statement. Each object has properties like name, column, table, database, and type. ```APIDOC ## .columns() ### Description This method is primarily used in conjunction with [raw mode](#rawtogglestate---this). It returns an array of objects, where each object describes a result column of the prepared statement. Each object has the following properties: - `.name`: the name (or alias) of the result column. - `.column`: the name of the originating table column, or `null` if it's an expression or subquery. - `.table`: the name of the originating table, or `null` if it's an expression or subquery. - `.database`: the name of the originating database, or `null` if it's an expression or subquery. - `.type`: the name of the [declared type](https://www.sqlite.org/datatype3.html#determination_of_column_affinity), or `null` if it's an expression or subquery. ### Method `columns()` ### Response #### Success Response - **array of objects**: Each object describes a result column with properties: `name`, `column`, `table`, `database`, `type`. ``` -------------------------------- ### Load SQLite Extension Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Loads a compiled SQLite extension into the current database connection. Ensure the extension is compatible with the library's SQLite version. ```javascript db.loadExtension('./my-extensions/compress.so'); ``` -------------------------------- ### .function(*name*, [*options*], *function*) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Registers a user-defined SQL function. This function can be called from SQL statements. It supports specifying the number of arguments, variable arguments, direct invocation only, and determinism. ```APIDOC ## .function(*name*, [*options*], *function*) -> *this* Registers a user-defined `function` so that it can be used by SQL statements. 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. If `options.directOnly` is `true`, the registered function can only be invoked from top-level SQL, and cannot be used in [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. If your function is [deterministic](https://en.wikipedia.org/wiki/Deterministic_algorithm), you can set `options.deterministic` to `true`, which may improve performance under some circumstances. ### Example Usage: ```js db.function('add2', (a, b) => a + b); db.prepare('SELECT add2(?, ?)').pluck().get(12, 4); // => 16 db.prepare('SELECT add2(?, ?)').pluck().get('foo', 'bar'); // => "foobar" db.prepare('SELECT add2(?, ?, ?)').pluck().get(12, 4, 18); // => Error: wrong number of arguments db.function('void', { deterministic: true, varargs: true }, () => {}); db.prepare("SELECT void() ").pluck().get(); // => null db.prepare("SELECT void(?, ?) ").pluck().get(55, 19); // => null ``` ``` -------------------------------- ### ES6 Module Database Usage Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/README.md Connect to a SQLite database and set the journal mode using ES6 module notation. Ensure 'options' are defined if needed. ```javascript import Database from 'better-sqlite3-multiple-ciphers'; const db = new Database('foobar.db', options); db.pragma('journal_mode = WAL'); ``` -------------------------------- ### Set Database Key with Buffer Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Decrypts or encrypts the database using a provided key as a Buffer. This is preferred over PRAGMA key when the key is binary data. It directly interfaces with the underlying sqlite3_key() function. ```javascript db.pragma(`cipher='aes256cbc' `) ``` ```javascript db.key(Buffer.from('password')); ``` -------------------------------- ### .bind([*...bindParameters*]) Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Binds the given parameters to the statement permanently. This is a performance optimization for executing the same prepared statement many times with the same bound parameters. ```APIDOC ## .bind([*...bindParameters*]) ### Description [Binds the given parameters](#binding-parameters) to the statement *permanently*. Unlike binding parameters upon execution, these parameters will stay bound to the prepared statement for its entire life. After a statement's parameters are bound this way, you may no longer provide it with execution-specific (temporary) bound parameters. This method is primarily used as a performance optimization when you need to execute the same prepared statement many times with the same bound parameters. ### Method `bind(*...bindParameters*)` ### Parameters #### Path Parameters - **...bindParameters**: The parameters to bind to the statement. ``` -------------------------------- ### Register Sequence Virtual Table with Default Parameter Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Registers a 'sequence' virtual table that generates numbers within a specified range. It demonstrates handling required and default parameters, requiring explicit 'parameters' declaration when default values are used. ```javascript db.table('sequence', { columns: ['value'], parameters: ['length', 'start'], rows: function* (length, start = 0) { if (length === undefined) { throw new TypeError('missing required parameter "length"'); } const end = start + length; for (let n = start; n < end; ++n) { yield { value: n }; } }, }); db.prepare('SELECT * FROM sequence(10)').pluck().all(); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ``` -------------------------------- ### Rekey Database with Buffer Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Encrypts or re-encrypts the database using a provided key as a Buffer. This is preferred over PRAGMA rekey for binary keys and directly uses sqlite3_rekey(). The database must be decrypted first if it is already encrypted. ```javascript db.pragma(`cipher='aes256cbc' `) ``` ```javascript db.key(Buffer.from('oldpassword')); ``` ```javascript db.rekey(Buffer.from('newpassword')); ``` -------------------------------- ### Mixed Parameter Binding Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Combine anonymous and named parameters in a single prepared statement. Ensure the order and types of parameters match the statement's placeholders. ```javascript const stmt = db.prepare('INSERT INTO people VALUES (@name, @name, ?)'); stmt.run(45, { name: 'Henry' }); ``` -------------------------------- ### Named Parameter Binding Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Supports SQLite's `@foo`, `:foo`, and `$foo` named parameter syntaxes. Pass parameters as an object where keys match the parameter names. ```javascript const stmt = db.prepare('INSERT INTO people VALUES (@firstName, @lastName, @age)'); const stmt = db.prepare('INSERT INTO people VALUES (:firstName, :lastName, :age)'); const stmt = db.prepare('INSERT INTO people VALUES ($firstName, $lastName, $age)'); const stmt = db.prepare('INSERT INTO people VALUES (@firstName, :lastName, $age)'); stmt.run({ firstName: 'John', lastName: 'Smith', age: 45 }); ``` -------------------------------- ### Register Regex Matches Virtual Table with Explicit Parameters Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Similar to the basic regex_matches table, but explicitly defines 'pattern' and 'text' as parameters for clarity. ```javascript db.table('regex_matches', { columns: ['match', 'capture'], parameters: ['pattern', 'text'], rows: function* (pattern, text) { ... }, }); ``` -------------------------------- ### Default Bundled SQLite Compilation Options Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/compilation.md These are the default compile-time options used for the bundled SQLite version in better-sqlite3-multiple-ciphers. They enable various features and configure SQLite's behavior. ```text HAVE_INT16_T=1 HAVE_INT32_T=1 HAVE_INT8_T=1 HAVE_STDINT_H=1 HAVE_UINT16_T=1 HAVE_UINT32_T=1 HAVE_UINT8_T=1 HAVE_USLEEP=1 SQLITE_DEFAULT_CACHE_SIZE=-16000 SQLITE_DEFAULT_FOREIGN_KEYS=1 SQLITE_DEFAULT_MEMSTATUS=0 SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 SQLITE_DQS=0 SQLITE_ENABLE_COLUMN_METADATA SQLITE_ENABLE_DBSTAT_VTAB SQLITE_ENABLE_DESERIALIZE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS5 SQLITE_ENABLE_GEOPOLY SQLITE_ENABLE_JSON1 SQLITE_ENABLE_MATH_FUNCTIONS SQLITE_ENABLE_PERCENTILE SQLITE_ENABLE_RTREE SQLITE_ENABLE_STAT4 SQLITE_ENABLE_UPDATE_DELETE_LIMIT SQLITE_LIKE_DOESNT_MATCH_BLOBS SQLITE_OMIT_DEPRECATED SQLITE_OMIT_PROGRESS_CALLBACK SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_TCL_VARIABLE SQLITE_SOUNDEX SQLITE_THREADSAFE=2 SQLITE_TRACE_SIZE_LIMIT=32 SQLITE_USER_AUTHENTICATION=0 SQLITE_USE_URI=0 ``` -------------------------------- ### Permanently Bind Parameters to a Statement Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use `.bind()` to permanently associate parameters with a prepared statement. This is a performance optimization for statements executed multiple times with the same parameters. Once bound permanently, execution-specific parameters cannot be used. ```javascript const stmt = db.prepare('SELECT * FROM cats WHERE name = ?').bind('Joey'); const cat = stmt.get(); console.log(cat.name); // => "Joey" ``` -------------------------------- ### Anonymous Parameter Binding Source: https://github.com/m4heshd/better-sqlite3-multiple-ciphers/blob/master/docs/api.md Use anonymous parameters with `?` placeholders for simple data insertion. Parameters can be passed as individual arguments, a single array, or multiple arrays. ```javascript const stmt = db.prepare('INSERT INTO people VALUES (?, ?, ?)'); // The following are equivalent. stmt.run('John', 'Smith', 45); stmt.run(['John', 'Smith', 45]); stmt.run(['John'], ['Smith', 45]); ```