Skip to content

Commit 67de7be

Browse files
committed
doc: correct and expand documentation for SQLTagStore
1 parent b757a8f commit 67de7be

File tree

1 file changed

+102
-40
lines changed

1 file changed

+102
-40
lines changed

doc/api/sqlite.md

Lines changed: 102 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,54 @@ added: v24.9.0
446446
**Default:** `1000`.
447447
* Returns: {SQLTagStore} A new SQL tag store for caching prepared statements.
448448

449-
Creates a new `SQLTagStore`, which is an LRU (Least Recently Used) cache for
450-
storing prepared statements. This allows for the efficient reuse of prepared
451-
statements by tagging them with a unique identifier.
449+
Creates a new [`SQLTagStore`][], which is an LRU (Least Recently Used) cache
450+
for storing prepared statements. This allows for the efficient reuse of
451+
prepared statements by tagging them with a unique identifier.
452452

453453
When a tagged SQL literal is executed, the `SQLTagStore` checks if a prepared
454-
statement for that specific SQL string already exists in the cache. If it does,
455-
the cached statement is used. If not, a new prepared statement is created,
456-
executed, and then stored in the cache for future use. This mechanism helps to
457-
avoid the overhead of repeatedly parsing and preparing the same SQL statements.
454+
statement for the corresponding SQL query string already exists in the cache.
455+
If it does, the cached statement is used. If not, a new prepared statement is
456+
created, executed, and then stored in the cache for future use. This mechanism
457+
helps to avoid the overhead of repeatedly parsing and preparing the same SQL
458+
statements.
459+
460+
Tagged statements bind the "placeholder" values from the template literal as
461+
parameters to the underlying prepared statement. That is to say,
462+
463+
```js
464+
tagStore.get`SELECT ${value}`;
465+
```
466+
467+
is equivalent to
468+
469+
```js
470+
db.prepare('SELECT ?').get(value);
471+
```
472+
473+
except that the tag store will cache the underlying prepared statement for
474+
future use.
475+
476+
The tag store will match a statement from the cache if the query strings
477+
(including the positions of any bound placeholders) are identical.
478+
479+
```js
480+
// The following statements will match in the cache:
481+
tagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`;
482+
tagStore.get`SELECT * FROM t1 WHERE id = ${12345} AND active = 1`;
483+
484+
// The following statements will not match, as the query strings
485+
// and bound placeholders differ:
486+
tagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`;
487+
tagStore.get`SELECT * FROM t1 WHERE id = 12345 AND active = 1`;
488+
489+
// The following statements will not match, as matches are case-sensitive:
490+
tagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`;
491+
tagStore.get`select * from t1 where id = ${id} and active = 1`;
492+
```
493+
494+
The only way of binding parameters in tagged statements is with the `${value}`
495+
syntax. Do not add parameter binding placeholders (`?` etc.) to the SQL query
496+
string itself.
458497

459498
```mjs
460499
import { DatabaseSync } from 'node:sqlite';
@@ -609,23 +648,6 @@ wrapper around [`sqlite3session_patchset()`][].
609648
Closes the session. An exception is thrown if the database or the session is not open. This method is a
610649
wrapper around [`sqlite3session_delete()`][].
611650

612-
## Class: `StatementSync`
613-
614-
<!-- YAML
615-
added: v22.5.0
616-
-->
617-
618-
This class represents a single [prepared statement][]. This class cannot be
619-
instantiated via its constructor. Instead, instances are created via the
620-
`database.prepare()` method. All APIs exposed by this class execute
621-
synchronously.
622-
623-
A prepared statement is an efficient binary representation of the SQL used to
624-
create it. Prepared statements are parameterizable, and can be invoked multiple
625-
times with different bound values. Parameters also offer protection against
626-
[SQL injection][] attacks. For these reasons, prepared statements are preferred
627-
over hand-crafted SQL strings when handling user input.
628-
629651
## Class: `SQLTagStore`
630652

631653
<!-- YAML
@@ -635,65 +657,86 @@ added: v24.9.0
635657
This class represents a single LRU (Least Recently Used) cache for storing
636658
prepared statements.
637659

638-
Instances of this class are created via the database.createSQLTagStore() method,
639-
not by using a constructor. The store caches prepared statements based on the
640-
provided SQL query string. When the same query is seen again, the store
660+
Instances of this class are created via the [`database.createSQLTagStore()`]
661+
method, not by using a constructor. The store caches prepared statements based
662+
on the provided SQL query string. When the same query is seen again, the store
641663
retrieves the cached statement and safely applies the new values through
642664
parameter binding, thereby preventing attacks like SQL injection.
643665

644666
The cache has a maxSize that defaults to 1000 statements, but a custom size can
645667
be provided (e.g., database.createSQLTagStore(100)). All APIs exposed by this
646668
class execute synchronously.
647669

648-
### `sqlTagStore.all(sqlTemplate[, ...values])`
670+
### `sqlTagStore.all(stringElements[, ...boundParameters])`
649671

650672
<!-- YAML
651673
added: v24.9.0
652674
-->
653675

654-
* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
655-
* `...values` {any} Values to be interpolated into the template literal.
676+
* `stringElements` {string\[]} Template literal elements containing the SQL
677+
query.
678+
* `...boundParameters` {null|number|bigint|string|Buffer|TypedArray|DataView}
679+
Parameter values to be bound to placeholders in the template string.
656680
* Returns: {Array} An array of objects representing the rows returned by the query.
657681

658-
Executes the given SQL query and returns all resulting rows as an array of objects.
682+
Executes the given SQL query and returns all resulting rows as an array of
683+
objects.
684+
685+
This function is intended to be used as a template literal tag, not to be
686+
called directly.
659687

660-
### `sqlTagStore.get(sqlTemplate[, ...values])`
688+
### `sqlTagStore.get(stringElements[, ...boundParameters])`
661689

662690
<!-- YAML
663691
added: v24.9.0
664692
-->
665693

666-
* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
667-
* `...values` {any} Values to be interpolated into the template literal.
694+
* `stringElements` {string\[]} Template literal elements containing the SQL
695+
query.
696+
* `...boundParameters` {null|number|bigint|string|Buffer|TypedArray|DataView}
697+
Parameter values to be bound to placeholders in the template string.
668698
* Returns: {Object | undefined} An object representing the first row returned by
669699
the query, or `undefined` if no rows are returned.
670700

671701
Executes the given SQL query and returns the first resulting row as an object.
672702

673-
### `sqlTagStore.iterate(sqlTemplate[, ...values])`
703+
This function is intended to be used as a template literal tag, not to be
704+
called directly.
705+
706+
### `sqlTagStore.iterate(stringElements[, ...boundParameters])`
674707

675708
<!-- YAML
676709
added: v24.9.0
677710
-->
678711

679-
* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
680-
* `...values` {any} Values to be interpolated into the template literal.
712+
* `stringElements` {string\[]} Template literal elements containing the SQL
713+
query.
714+
* `...boundParameters` {null|number|bigint|string|Buffer|TypedArray|DataView}
715+
Parameter values to be bound to placeholders in the template string.
681716
* Returns: {Iterator} An iterator that yields objects representing the rows returned by the query.
682717

683718
Executes the given SQL query and returns an iterator over the resulting rows.
684719

685-
### `sqlTagStore.run(sqlTemplate[, ...values])`
720+
This function is intended to be used as a template literal tag, not to be
721+
called directly.
722+
723+
### `sqlTagStore.run(stringElements[, ...boundParameters])`
686724

687725
<!-- YAML
688726
added: v24.9.0
689727
-->
690728

691-
* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
692-
* `...values` {any} Values to be interpolated into the template literal.
729+
* `stringElements` {string\[]} Template literal elements containing the SQL
730+
query.
731+
* `...boundParameters` {null|number|bigint|string|Buffer|TypedArray|DataView}
732+
Parameter values to be bound to placeholders in the template string.
693733
* Returns: {Object} An object containing information about the execution, including `changes` and `lastInsertRowid`.
694734

695735
Executes the given SQL query, which is expected to not return any rows (e.g., INSERT, UPDATE, DELETE).
696736

737+
This function is intended to be used as a template literal tag, not to be
738+
called directly.
739+
697740
### `sqlTagStore.size()`
698741

699742
<!-- YAML
@@ -740,6 +783,23 @@ added: v24.9.0
740783

741784
An alias for `sqlTagStore.reset()`.
742785

786+
## Class: `StatementSync`
787+
788+
<!-- YAML
789+
added: v22.5.0
790+
-->
791+
792+
This class represents a single [prepared statement][]. This class cannot be
793+
instantiated via its constructor. Instead, instances are created via the
794+
`database.prepare()` method. All APIs exposed by this class execute
795+
synchronously.
796+
797+
A prepared statement is an efficient binary representation of the SQL used to
798+
create it. Prepared statements are parameterizable, and can be invoked multiple
799+
times with different bound values. Parameters also offer protection against
800+
[SQL injection][] attacks. For these reasons, prepared statements are preferred
801+
over hand-crafted SQL strings when handling user input.
802+
743803
### `statement.all([namedParameters][, ...anonymousParameters])`
744804

745805
<!-- YAML
@@ -1309,7 +1369,9 @@ callback function to indicate what type of operation is being authorized.
13091369
[`SQLITE_DETERMINISTIC`]: https://www.sqlite.org/c3ref/c_deterministic.html
13101370
[`SQLITE_DIRECTONLY`]: https://www.sqlite.org/c3ref/c_deterministic.html
13111371
[`SQLITE_MAX_FUNCTION_ARG`]: https://www.sqlite.org/limits.html#max_function_arg
1372+
[`SQLTagStore`]: #class-sqltagstore
13121373
[`database.applyChangeset()`]: #databaseapplychangesetchangeset-options
1374+
[`database.createSQLTagStore()`]: #databasecreatesqltagstoremaxsize
13131375
[`database.setAuthorizer()`]: #databasesetauthorizercallback
13141376
[`sqlite3_backup_finish()`]: https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish
13151377
[`sqlite3_backup_init()`]: https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit

0 commit comments

Comments
 (0)