sqlite: add tagged template · nodejs/node@5563361
@@ -351,6 +351,53 @@ added: v22.5.0
351351Compiles a SQL statement into a [prepared statement][]. This method is a wrapper
352352around [`sqlite3_prepare_v2()`][].
353353354+### `database.createSQLTagStore([maxSize])`
355+356+<!-- YAML
357+added: REPLACEME
358+-->
359+360+* `maxSize` {integer} The maximum number of prepared statements to cache.
361+**Default:** `1000`.
362+* Returns: {SQLTagStore} A new SQL tag store for caching prepared statements.
363+364+Creates a new `SQLTagStore`, which is an LRU (Least Recently Used) cache for
365+storing prepared statements. This allows for the efficient reuse of prepared
366+statements by tagging them with a unique identifier.
367+368+When a tagged SQL literal is executed, the `SQLTagStore` checks if a prepared
369+statement for that specific SQL string already exists in the cache. If it does,
370+the cached statement is used. If not, a new prepared statement is created,
371+executed, and then stored in the cache for future use. This mechanism helps to
372+avoid the overhead of repeatedly parsing and preparing the same SQL statements.
373+374+```mjs
375+import { DatabaseSync } from 'node:sqlite';
376+377+const db = new DatabaseSync(':memory:');
378+const sql = db.createSQLTagStore();
379+380+db.exec('CREATE TABLE users (id INT, name TEXT)');
381+382+// Using the 'run' method to insert data.
383+// The tagged literal is used to identify the prepared statement.
384+sql.run`INSERT INTO users VALUES (1, 'Alice')`;
385+sql.run`INSERT INTO users VALUES (2, 'Bob')`;
386+387+// Using the 'get' method to retrieve a single row.
388+const id = 1;
389+const user = sql.get`SELECT * FROM users WHERE id = ${id}`;
390+console.log(user); // { id: 1, name: 'Alice' }
391+392+// Using the 'all' method to retrieve all rows.
393+const allUsers = sql.all`SELECT * FROM users ORDER BY id`;
394+console.log(allUsers);
395+// [
396+// { id: 1, name: 'Alice' },
397+// { id: 2, name: 'Bob' }
398+// ]
399+```
400+354401### `database.createSession([options])`
355402356403<!-- YAML
@@ -494,6 +541,120 @@ times with different bound values. Parameters also offer protection against
494541[SQL injection][] attacks. For these reasons, prepared statements are preferred
495542over hand-crafted SQL strings when handling user input.
496543544+## Class: `SQLTagStore`
545+546+<!-- YAML
547+added: REPLACEME
548+-->
549+550+This class represents a single LRU (Least Recently Used) cache for storing
551+prepared statements.
552+553+Instances of this class are created via the database.createSQLTagStore() method,
554+not by using a constructor. The store caches prepared statements based on the
555+provided SQL query string. When the same query is seen again, the store
556+retrieves the cached statement and safely applies the new values through
557+parameter binding, thereby preventing attacks like SQL injection.
558+559+The cache has a maxSize that defaults to 1000 statements, but a custom size can
560+be provided (e.g., database.createSQLTagStore(100)). All APIs exposed by this
561+class execute synchronously.
562+563+### `sqlTagStore.all(sqlTemplate[, ...values])`
564+565+<!-- YAML
566+added: REPLACEME
567+-->
568+569+* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
570+* `...values` {any} Values to be interpolated into the template literal.
571+* Returns: {Array} An array of objects representing the rows returned by the query.
572+573+Executes the given SQL query and returns all resulting rows as an array of objects.
574+575+### `sqlTagStore.get(sqlTemplate[, ...values])`
576+577+<!-- YAML
578+added: REPLACEME
579+-->
580+581+* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
582+* `...values` {any} Values to be interpolated into the template literal.
583+* Returns: {Object | undefined} An object representing the first row returned by
584+ the query, or `undefined` if no rows are returned.
585+586+Executes the given SQL query and returns the first resulting row as an object.
587+588+### `sqlTagStore.iterate(sqlTemplate[, ...values])`
589+590+<!-- YAML
591+added: REPLACEME
592+-->
593+594+* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
595+* `...values` {any} Values to be interpolated into the template literal.
596+* Returns: {Iterator} An iterator that yields objects representing the rows returned by the query.
597+598+Executes the given SQL query and returns an iterator over the resulting rows.
599+600+### `sqlTagStore.run(sqlTemplate[, ...values])`
601+602+<!-- YAML
603+added: REPLACEME
604+-->
605+606+* `sqlTemplate` {Template Literal} A template literal containing the SQL query.
607+* `...values` {any} Values to be interpolated into the template literal.
608+* Returns: {Object} An object containing information about the execution, including `changes` and `lastInsertRowid`.
609+610+Executes the given SQL query, which is expected to not return any rows (e.g., INSERT, UPDATE, DELETE).
611+612+### `sqlTagStore.size()`
613+614+<!-- YAML
615+added: REPLACEME
616+-->
617+618+* Returns: {integer} The number of prepared statements currently in the cache.
619+620+A read-only property that returns the number of prepared statements currently in the cache.
621+622+### `sqlTagStore.capacity`
623+624+<!-- YAML
625+added: REPLACEME
626+-->
627+628+* Returns: {integer} The maximum number of prepared statements the cache can hold.
629+630+A read-only property that returns the maximum number of prepared statements the cache can hold.
631+632+### `sqlTagStore.db`
633+634+<!-- YAML
635+added: REPLACEME
636+-->
637+638+* {DatabaseSync} The `DatabaseSync` instance that created this `SQLTagStore`.
639+640+A read-only property that returns the `DatabaseSync` object associated with this `SQLTagStore`.
641+642+### `sqlTagStore.reset()`
643+644+<!-- YAML
645+added: REPLACEME
646+-->
647+648+Resets the LRU cache, clearing all stored prepared statements.
649+650+### `sqlTagStore.clear()`
651+652+<!-- YAML
653+added: REPLACEME
654+-->
655+656+An alias for `sqlTagStore.reset()`.
657+497658### `statement.all([namedParameters][, ...anonymousParameters])`
498659499660<!-- YAML