@@ -351,6 +351,53 @@ added: v22.5.0 |
351 | 351 | Compiles a SQL statement into a [prepared statement][]. This method is a wrapper |
352 | 352 | around [`sqlite3_prepare_v2()`][]. |
353 | 353 |
|
| 354 | +### `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 | + |
354 | 401 | ### `database.createSession([options])` |
355 | 402 |
|
356 | 403 | <!-- YAML |
@@ -494,6 +541,120 @@ times with different bound values. Parameters also offer protection against |
494 | 541 | [SQL injection][] attacks. For these reasons, prepared statements are preferred |
495 | 542 | over hand-crafted SQL strings when handling user input. |
496 | 543 |
|
| 544 | +## 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 | + |
497 | 658 | ### `statement.all([namedParameters][, ...anonymousParameters])` |
498 | 659 |
|
499 | 660 | <!-- YAML |
|