@@ -446,15 +446,68 @@ 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 a Least Recently Used (LRU ) cache
450+ for storing prepared statements. This allows for the efficient reuse of
451+ prepared statements by tagging them with a unique identifier.
452452
453453When 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. For example:
462+
463+ ``` js
464+ sqlTagStore .get ` SELECT ${ value} ` ;
465+ ```
466+
467+ is equivalent to:
468+
469+ ``` js
470+ db .prepare (' SELECT ?' ).get (value);
471+ ```
472+
473+ However, in the first example, the tag store will cache the underlying prepared
474+ statement for future use.
475+
476+ > ** Note:** The ` ${value} ` syntax in tagged statements _ binds_ a parameter to
477+ > the prepared statement. This differs from its behavior in _ untagged_ template
478+ > literals, where it performs string interpolation.
479+ >
480+ > ``` js
481+ > // This a safe example of binding a parameter to a tagged statement.
482+ > sqlTagStore .run ` INSERT INTO t1 (id) VALUES (${ id} )` ;
483+ >
484+ > // This is an *unsafe* example of an untagged template string.
485+ > // `id` is interpolated into the query text as a string.
486+ > // This can lead to SQL injection and data corruption.
487+ > db .run (` INSERT INTO t1 (id) VALUES (${ id} )` );
488+ > ` ` `
489+
490+ The tag store will match a statement from the cache if the query strings
491+ (including the positions of any bound placeholders) are identical.
492+
493+ ` ` ` js
494+ // The following statements will match in the cache:
495+ sqlTagStore .get ` SELECT * FROM t1 WHERE id = ${ id} AND active = 1` ;
496+ sqlTagStore .get ` SELECT * FROM t1 WHERE id = ${ 12345 } AND active = 1` ;
497+
498+ // The following statements will not match, as the query strings
499+ // and bound placeholders differ:
500+ sqlTagStore .get ` SELECT * FROM t1 WHERE id = ${ id} AND active = 1` ;
501+ sqlTagStore .get ` SELECT * FROM t1 WHERE id = 12345 AND active = 1` ;
502+
503+ // The following statements will not match, as matches are case-sensitive:
504+ sqlTagStore .get ` SELECT * FROM t1 WHERE id = ${ id} AND active = 1` ;
505+ sqlTagStore .get ` select * from t1 where id = ${ id} and active = 1` ;
506+ ```
507+
508+ The only way of binding parameters in tagged statements is with the ` ${value} `
509+ syntax. Do not add parameter binding placeholders (` ? ` etc.) to the SQL query
510+ string itself.
458511
459512``` mjs
460513import { DatabaseSync } from ' node:sqlite' ;
@@ -609,23 +662,6 @@ wrapper around [`sqlite3session_patchset()`][].
609662Closes the session. An exception is thrown if the database or the session is not open. This method is a
610663wrapper around [ ` sqlite3session_delete() ` ] [ ] .
611664
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-
629665## Class: ` SQLTagStore `
630666
631667<!-- YAML
@@ -635,65 +671,86 @@ added: v24.9.0
635671This class represents a single LRU (Least Recently Used) cache for storing
636672prepared statements.
637673
638- Instances of this class are created via the database.createTagStore() 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
674+ Instances of this class are created via the [ ` database.createTagStore() ` ] [ ]
675+ method, not by using a constructor. The store caches prepared statements based
676+ on the provided SQL query string. When the same query is seen again, the store
641677retrieves the cached statement and safely applies the new values through
642678parameter binding, thereby preventing attacks like SQL injection.
643679
644680The cache has a maxSize that defaults to 1000 statements, but a custom size can
645- be provided (e.g., database.createTagStore(100)). All APIs exposed by this
681+ be provided (e.g., ` database.createTagStore(100) ` ). All APIs exposed by this
646682class execute synchronously.
647683
648- ### ` sqlTagStore.all(sqlTemplate [, ...values ]) `
684+ ### ` sqlTagStore.all(stringElements [, ...boundParameters ]) `
649685
650686<!-- YAML
651687added: v24.9.0
652688-->
653689
654- * ` sqlTemplate ` {Template Literal} A template literal containing the SQL query.
655- * ` ...values ` {any} Values to be interpolated into the template literal.
690+ * ` stringElements ` {string\[ ] } Template literal elements containing the SQL
691+ query.
692+ * ` ...boundParameters ` {null|number|bigint|string|Buffer|TypedArray|DataView}
693+ Parameter values to be bound to placeholders in the template string.
656694* Returns: {Array} An array of objects representing the rows returned by the query.
657695
658- Executes the given SQL query and returns all resulting rows as an array of objects.
696+ Executes the given SQL query and returns all resulting rows as an array of
697+ objects.
698+
699+ This function is intended to be used as a template literal tag, not to be
700+ called directly.
659701
660- ### ` sqlTagStore.get(sqlTemplate [, ...values ]) `
702+ ### ` sqlTagStore.get(stringElements [, ...boundParameters ]) `
661703
662704<!-- YAML
663705added: v24.9.0
664706-->
665707
666- * ` sqlTemplate ` {Template Literal} A template literal containing the SQL query.
667- * ` ...values ` {any} Values to be interpolated into the template literal.
708+ * ` stringElements ` {string\[ ] } Template literal elements containing the SQL
709+ query.
710+ * ` ...boundParameters ` {null|number|bigint|string|Buffer|TypedArray|DataView}
711+ Parameter values to be bound to placeholders in the template string.
668712* Returns: {Object | undefined} An object representing the first row returned by
669713 the query, or ` undefined ` if no rows are returned.
670714
671715Executes the given SQL query and returns the first resulting row as an object.
672716
673- ### ` sqlTagStore.iterate(sqlTemplate[, ...values]) `
717+ This function is intended to be used as a template literal tag, not to be
718+ called directly.
719+
720+ ### ` sqlTagStore.iterate(stringElements[, ...boundParameters]) `
674721
675722<!-- YAML
676723added: v24.9.0
677724-->
678725
679- * ` sqlTemplate ` {Template Literal} A template literal containing the SQL query.
680- * ` ...values ` {any} Values to be interpolated into the template literal.
726+ * ` stringElements ` {string\[ ] } Template literal elements containing the SQL
727+ query.
728+ * ` ...boundParameters ` {null|number|bigint|string|Buffer|TypedArray|DataView}
729+ Parameter values to be bound to placeholders in the template string.
681730* Returns: {Iterator} An iterator that yields objects representing the rows returned by the query.
682731
683732Executes the given SQL query and returns an iterator over the resulting rows.
684733
685- ### ` sqlTagStore.run(sqlTemplate[, ...values]) `
734+ This function is intended to be used as a template literal tag, not to be
735+ called directly.
736+
737+ ### ` sqlTagStore.run(stringElements[, ...boundParameters]) `
686738
687739<!-- YAML
688740added: v24.9.0
689741-->
690742
691- * ` sqlTemplate ` {Template Literal} A template literal containing the SQL query.
692- * ` ...values ` {any} Values to be interpolated into the template literal.
743+ * ` stringElements ` {string\[ ] } Template literal elements containing the SQL
744+ query.
745+ * ` ...boundParameters ` {null|number|bigint|string|Buffer|TypedArray|DataView}
746+ Parameter values to be bound to placeholders in the template string.
693747* Returns: {Object} An object containing information about the execution, including ` changes ` and ` lastInsertRowid ` .
694748
695749Executes the given SQL query, which is expected to not return any rows (e.g., INSERT, UPDATE, DELETE).
696750
751+ This function is intended to be used as a template literal tag, not to be
752+ called directly.
753+
697754### ` sqlTagStore.size() `
698755
699756<!-- YAML
@@ -710,7 +767,7 @@ A read-only property that returns the number of prepared statements currently in
710767added: v24.9.0
711768-->
712769
713- * Returns : {integer} The maximum number of prepared statements the cache can hold.
770+ * Type : {integer}
714771
715772A read-only property that returns the maximum number of prepared statements the cache can hold.
716773
@@ -720,25 +777,34 @@ A read-only property that returns the maximum number of prepared statements the
720777added: v24.9.0
721778-->
722779
723- * {DatabaseSync} The ` DatabaseSync ` instance that created this ` SQLTagStore ` .
780+ * Type: {DatabaseSync}
724781
725782A read-only property that returns the ` DatabaseSync ` object associated with this ` SQLTagStore ` .
726783
727- ### ` sqlTagStore.reset () `
784+ ### ` sqlTagStore.clear () `
728785
729786<!-- YAML
730787added: v24.9.0
731788-->
732789
733790Resets the LRU cache, clearing all stored prepared statements.
734791
735- ### ` sqlTagStore.clear() `
792+ ## Class: ` StatementSync `
736793
737794<!-- YAML
738- added: v24.9 .0
795+ added: v22.5 .0
739796-->
740797
741- An alias for ` sqlTagStore.reset() ` .
798+ This class represents a single [ prepared statement] [ ] . This class cannot be
799+ instantiated via its constructor. Instead, instances are created via the
800+ ` database.prepare() ` method. All APIs exposed by this class execute
801+ synchronously.
802+
803+ A prepared statement is an efficient binary representation of the SQL used to
804+ create it. Prepared statements are parameterizable, and can be invoked multiple
805+ times with different bound values. Parameters also offer protection against
806+ [ SQL injection] [ ] attacks. For these reasons, prepared statements are preferred
807+ over hand-crafted SQL strings when handling user input.
742808
743809### ` statement.all([namedParameters][, ...anonymousParameters]) `
744810
@@ -1309,7 +1375,9 @@ callback function to indicate what type of operation is being authorized.
13091375[ `SQLITE_DETERMINISTIC` ] : https://www.sqlite.org/c3ref/c_deterministic.html
13101376[ `SQLITE_DIRECTONLY` ] : https://www.sqlite.org/c3ref/c_deterministic.html
13111377[ `SQLITE_MAX_FUNCTION_ARG` ] : https://www.sqlite.org/limits.html#max_function_arg
1378+ [ `SQLTagStore` ] : #class-sqltagstore
13121379[ `database.applyChangeset()` ] : #databaseapplychangesetchangeset-options
1380+ [ `database.createTagStore()` ] : #databasecreatetagstoremaxsize
13131381[ `database.setAuthorizer()` ] : #databasesetauthorizercallback
13141382[ `sqlite3_backup_finish()` ] : https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish
13151383[ `sqlite3_backup_init()` ] : https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit
0 commit comments