Skip to content

Commit

Permalink
sqlite: add support for SQLite Session Extension
Browse files Browse the repository at this point in the history
  • Loading branch information
louwers committed Nov 2, 2024
1 parent e124b0f commit 8f45730
Show file tree
Hide file tree
Showing 7 changed files with 758 additions and 1 deletion.
4 changes: 4 additions & 0 deletions deps/sqlite/sqlite.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
'xcode_settings': {
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
},
'defines': [
'SQLITE_ENABLE_SESSION',
'SQLITE_ENABLE_PREUPDATE_HOOK'
],
'include_dirs': ['.'],
'sources': [
'<@(sqlite_sources)',
Expand Down
75 changes: 75 additions & 0 deletions doc/api/sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,74 @@ added: v22.5.0
Compiles a SQL statement into a [prepared statement][]. This method is a wrapper
around [`sqlite3_prepare_v2()`][].

### `database.createSession([options])`

* `options` {Object} An optional object used to configure the session.
* `table` {string} When provided, only changes to this table are tracked by the created session.
By default, changes to all tables are tracked.
* `db` {string} Name of the database to track. Default: `'main'`.
* Returns: {Session} A session handle.

Creates and attaches a session to the database. This method is a wrapper around [`sqlite3session_create()`][] and [`sqlite3session_attach()`][].

### `database.applyChangeset(changeset[, options])`

* `changeset` {Uint8Array} A binary changeset or patchset.
* `options` {Object} An optional object to configure how changes are applied.
* `filter` {Function} Optional function. Skips changes when a truthy value is returned from it.
Takes the name of the table that a change targets as first argument. When this option is not
provided all changes are attempted.
* `onConflict` {number} Determines how conflicts are handled. When provided, must be one of the values below:
* `SQLITE_CHANGESET_OMIT`: conflicting changes are omitted.
* `SQLITE_CHANGESET_REPLACE`: conflicting changes replace existing values.
* `SQLITE_CHANGESET_ABORT`: abort on conflict and roll back databsase (default).
* Returns: {boolean} Whether the changeset was applied succesfully without being aborted.

An exception is thrown if the database is not
open. This method is a wrapper around [`sqlite3changeset_apply()`][].

Example usage is demonstrated below.

```js
const database1 = new DatabaseSync(':memory:');
const database2 = new DatabaseSync(':memory:');

database1.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)');
database2.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)');

const session = database1.createSession();

const insert = database1.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
insert.run(1, 'hello');
insert.run(2, 'world');

const changeset = session.changeset();
database2.applyChangeset(changeset);
// Now database2 contains the same data as database1
```

## Class: `Session`

### `session.changeset()`

* Returns: {Uint8Array} Binary changeset that can be applied to other databases.

Retrieves a changeset containing all changes since the changeset was created. Can be called multiple times.
An exception is thrown if the database or the session is not open. This method is a wrapper around [`sqlite3session_changeset()`][].

### `session.patchset()`

* Returns: {Uint8Array} Binary patchset that can be applied to other databases.

Similar to the method above, but generates a more compact patchset. See [Changesets and Patchsets][]
in the documentation of SQLite. An exception is thrown if the database or the session is not open. This method is a
wrapper around [`sqlite3session_patchset()`][].

### `session.close()`.

Closes the session. An exception is thrown if the database or the session is not open. This method is a
wrapper around [`sqlite3session_delete()`][].

## Class: `StatementSync`

<!-- YAML
Expand Down Expand Up @@ -326,6 +394,7 @@ exception.
| `TEXT` | {string} |
| `BLOB` | {Uint8Array} |

[Changesets and Patchsets]: https://www.sqlite.org/sessionintro.html#changesets_and_patchsets
[SQL injection]: https://en.wikipedia.org/wiki/SQL_injection
[`--experimental-sqlite`]: cli.md#--experimental-sqlite
[`PRAGMA foreign_keys`]: https://www.sqlite.org/pragma.html#pragma_foreign_keys
Expand All @@ -336,6 +405,12 @@ exception.
[`sqlite3_last_insert_rowid()`]: https://www.sqlite.org/c3ref/last_insert_rowid.html
[`sqlite3_prepare_v2()`]: https://www.sqlite.org/c3ref/prepare.html
[`sqlite3_sql()`]: https://www.sqlite.org/c3ref/expanded_sql.html
[`sqlite3changeset_apply()`]: https://www.sqlite.org/session/sqlite3changeset_apply.html
[`sqlite3session_attach()`]: https://www.sqlite.org/session/sqlite3session_attach.html
[`sqlite3session_changeset()`]: https://www.sqlite.org/session/sqlite3session_changeset.html
[`sqlite3session_create()`]: https://www.sqlite.org/session/sqlite3session_create.html
[`sqlite3session_delete()`]: https://www.sqlite.org/session/sqlite3session_delete.html
[`sqlite3session_patchset()`]: https://www.sqlite.org/session/sqlite3session_patchset.html
[connection]: https://www.sqlite.org/c3ref/sqlite3.html
[data types]: https://www.sqlite.org/datatype3.html
[double-quoted string literals]: https://www.sqlite.org/quirks.html#dblquote
Expand Down
1 change: 1 addition & 0 deletions src/env_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@
V(shutdown_wrap_template, v8::ObjectTemplate) \
V(socketaddress_constructor_template, v8::FunctionTemplate) \
V(sqlite_statement_sync_constructor_template, v8::FunctionTemplate) \
V(sqlite_session_constructor_template, v8::FunctionTemplate) \
V(streambaseentry_ctor_template, v8::FunctionTemplate) \
V(streambaseoutputstream_constructor_template, v8::ObjectTemplate) \
V(streamentry_ctor_template, v8::FunctionTemplate) \
Expand Down
Loading

0 comments on commit 8f45730

Please sign in to comment.