node-sqlite

repository·master·Indexed 21 days ago

https://github.com/kriasoft/node-sqlite

A TypeScript wrapper for the sqlite3 Node.js driver that adds ES6 Promise support and a built-in SQL-based migrations API. It provides a promisified interface for executing queries via methods like get(), all(), run(), and exec(), as well as support for prepared statements and row-by-row processing with each(). The library includes a migrations API that supports structured SQL files with Up and Down blocks for schema changes and rollbacks.

Tokens
11.5K
Snippets
53
Records
58
Agent score
75%

What's inside node-sqlite

  1. Manage Statement lifecycle with bind, reset, and finalize

    master

    To manage the state and resources of a prepared statement, use the following methods:

    • bind(...params): Binds parameters to the statement. This completely resets the statement object, the row cursor, and removes all previously bound parameters.
    • reset(): Resets the row cursor but preserves the current parameter bindings. Use this to re-execute the same query with the same parameters.
    • finalize(): Releases the statement resources. After calling this, all further calls on the statement object will throw errors. Use this to prevent long delays or database locks, especially after using get().
    // Example: Reusing a statement with reset
    await stmt.bind('param1', 'param2');
    await stmt.run();
    
    await stmt.reset(); // Resets cursor, keeps bindings
    await stmt.run();
    
    await stmt.finalize(); // Clean up
  2. Implement SQL-based migrations using Up and Down blocks

    master

    When creating migration files for this project, use a structured SQL format that separates the forward migration (Up) from the rollback migration (Down). This allows you to apply changes to the schema and revert them if necessary.

    Each migration file should follow this pattern:

    1. Up section: Contains the SQL commands to apply the changes (e.g., CREATE TABLE, CREATE INDEX, INSERT).
    2. Down section: Contains the SQL commands to undo exactly what the Up section did (e.g., DROP TABLE, DROP INDEX).

    Use comments like -- Up and -- Down to clearly demarcate these sections within your .sql files.

    --------------------------------------------------------------------------------
    -- Up
    --------------------------------------------------------------------------------
    
    CREATE TABLE Category (
      id   INTEGER PRIMARY KEY,
      name TEXT    NOT NULL
    );
    
    --------------------------------------------------------------------------------
    -- Down
    --------------------------------------------------------------------------------
    
    DROP TABLE Category;
  3. Install `sqlite` and `sqlite3`

    master

    To use this library, you must install both the sqlite wrapper and a database driver like sqlite3.

    • sqlite: The wrapper library that adds ES6 Promises and a migrations API. v4 targets Node.js 10 and above.
    • sqlite3: The recommended database driver.

    If you are using an older version of Node.js, install sqlite@3 instead.

    # Install the driver
    $ npm install sqlite3 --save
    
    # Install the wrapper (v4 for Node.js 10+)
    $ npm install sqlite --save
    
    # For legacy Node.js versions
    $ npm install sqlite@3 --save
  4. Configure the ISqlite Config interface

    master

    The Config interface is used to initialize a SQLite database connection. It requires a driver and a filename, and accepts an optional mode to control access permissions.

    Properties

    PropertyTypeDescription
    driveranyThe database driver class. Most users will provide the Database class from the sqlite3 package. Any library conforming to the sqlite3 API is acceptable.
    filenamestringThe path to the database file. Use ':memory:' for an anonymous in-memory database, or an empty string '' for an anonymous disk-based database. Note that anonymous databases are not persisted and contents are lost when the handle is closed.
    mode?numberAn optional bitmask representing SQLite open modes. It can include sqlite3.OPEN_READONLY, sqlite3.OPEN_READWRITE, and sqlite3.OPEN_CREATE. The default value is OPEN_READWRITE | OPEN_CREATE.
    import sqlite3 from 'sqlite3';
    
    const config = {
      driver: sqlite3.Database,
      filename: ':memory:',
      mode: sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE
    };
  5. Use SQL statements and template strings

    master

    The library supports two ways to provide SQL for execution via the SqlType type:

    1. Raw SQL String: A standard string containing the SQL command.
    2. SQLStatement Object: An object containing the sql string and an optional values array for parameter binding.

    This allows for both simple queries and prepared statements with parameterized values.

    // Using a raw string
    const query1: ISqlite.SqlType = "SELECT * FROM users";
    
    // Using a SQLStatement object
    const query2: ISqlite.SqlType = {
      sql: "SELECT * FROM users WHERE id = ?",
      values: [1]
    };
  6. Open a database with caching

    master

    To enable the database object cache, use sqlite3.cached.Database as the driver in the open configuration.

    import sqlite3 from 'sqlite3'
    import { open } from 'sqlite'
    
    (async () => {
        const db = await open({
          filename: '/tmp/database.db',
          driver: sqlite3.cached.Database
        })
    })()
  7. Use ES6 tagged template strings with SQL

    master

    The library is compatible with sql-template-strings. This allows you to write cleaner, safer queries using template literals.

    import SQL from 'sql-template-strings'
    
    const book = 'harry potter';
    const author = 'J. K. Rowling';
    
    const data = await db.all(SQL`SELECT author FROM books WHERE name = ${book} AND author = ${author}`);
  8. Open a database with open()

    master

    The open function is the primary entry point for the library. It initializes a connection to a SQLite database based on the provided configuration and returns a Database instance. This instance is used to execute queries and manage the database lifecycle.

    Parameters:

    • config: A Config object specifying the database driver and connection details (such as the file path or in-memory settings).
    import { open } from 'sqlite';
    
    const db = await open({
      filename: './database.db',
      driver: sqlite3.Database
    });
  9. Execute multiple statements with exec()

    master

    Use exec() to run a string containing one or more SQL statements. No result rows are retrieved.

    Constraints:

    • It only executes statements up to the first NULL byte.
    • Comments are not allowed and will cause runtime errors.
    • If a query fails, subsequent statements will not execute. To ensure atomicity, wrap the string in a transaction.
    await db.exec('CREATE TABLE test (id INTEGER); INSERT INTO test VALUES (1);');
  10. Open a database connection

    master

    Use the open function to create a database connection. You must provide a filename and a driver (typically sqlite3.Database).

    Configuration Options

    • filename: A string representing the file path. Use ":memory:" for an anonymous in-memory database or an empty string for an anonymous disk-based database.
    • driver: The database driver class (e.g., sqlite3.Database). Any library conforming to the sqlite3 API can be used.
    • mode (optional): One or more of sqlite3.OPEN_READONLY, sqlite3.OPEN_READWRITE, and sqlite3.OPEN_CREATE. The default is OPEN_READWRITE | OPEN_CREATE.
    import sqlite3 from 'sqlite3'
    import { open } from 'sqlite'
    
    (async () => {
        const db = await open({
          filename: '/tmp/database.db',
          driver: sqlite3.Database
        })
    })()