npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-sqlite3-wasm

v0.8.26

Published

WebAssembly port of SQLite3 for Node.js with file system access

Downloads

7,705

Readme

node-sqlite3-wasm

npm SQLite

WebAssembly build of SQLite3 for Node.js

node-sqlite3-wasm is a port of SQLite3 to WebAssembly for Node.js with file system access. node-sqlite3-wasm brings SQLite3 to your Node.js environment without recompiling on every target platform. This is especially useful for Electron applications.

The port to WebAssembly that SQLite introduced in version 3.40.0 only targets web browsers but not Node.js. Other WebAssembly ports also target Node.js, most notably sql.js, but none supports persistent storage with direct file access. There also exist native bindings like better-sqlite3 or node-sqlite3. However, native bindings must be recompiled for every target platform or pre-built binaries must be shipped. This is tedious, especially for Electron deployments.

node-sqlite3-wasm supports persistent storage with direct file access by implementing an SQLite OS Interface or "VFS" that translates SQLite file access to Node.js' file system API.

node-sqlite3-wasm is currently based on SQLite 3.47.0.

Getting Started

To install node-sqlite3-wasm, run

npm install node-sqlite3-wasm

To use it, run

const { Database } = require("node-sqlite3-wasm");
const db = new Database("database.db");

Important: node-sqlite3-wasm is not fully garbage-collected. You have to manually close a database, otherwise you risk memory leaks (see Database.close()). Also, if you use prepared statements explicitly (see Database.prepare()), you have to manually finalize them. Alternatively, the Database class provides the convenience methods

These convenience methods use a prepared statement internally and take care of finalizing it.

Note: Foreign key support is enabled by default.

Example

const { Database } = require("node-sqlite3-wasm");
const db = new Database("database.db");

db.exec(
  "DROP TABLE IF EXISTS employees; " +
    "CREATE TABLE IF NOT EXISTS employees (name TEXT, salary INTEGER)"
);

db.run("INSERT INTO employees VALUES (:n, :s)", {
  ":n": "James",
  ":s": 50000,
});

const r = db.all("SELECT * from employees");
console.log(r);
// [ { name: 'James', salary: 50000 } ]

db.close();

API

class Database

Constructor

Methods

Properties

new Database(path, [options])

Creates a new database connection. By default, the database file is created if it doesn't exist.

Important: You have to manually close the database, otherwise you risk memory leaks (see Database.close()).

Arguments

  • path: the path to the database file
  • options (optional)
    • fileMustExist (default: false): if the database file does not exist it will not be created. Instead an SQLite3Error will be thrown. This option is ignored if readOnly is true.
    • readOnly (default: false): opens the database in read-only mode
const db = new Database("database.db");
const db = new Database("database.db", { fileMustExist: true });

Database.all(sql, [values, options]) -> rows

Creates a prepared statement, executes it with the given values and returns the resulting rows as an array of objects. The prepared statement is finalized automatically.

Arguments

  • sql: string containing the SQL statement
  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
  • options (optional)
    • expand (default: false): if true, each returned row is a nested object with keys corresponding to tables in the query. If a result column is an expression or subquery, it will be returned under the key $.
db.all("SELECT * FROM book");
db.all("SELECT * FROM book WHERE title = ?", "The Little Prince");
db.all("SELECT * FROM book WHERE title = :t", { ":t": "The Little Prince" });
db.all("SELECT * FROM book WHERE title IN (?, ?)", [
  "The Little Prince",
  "The Hobbit",
]);

Database.close()

Closes the database.

Important: You have to manually close the database, otherwise you risk memory leaks.

Important: Closing the database with Database.close() does not automatically finalize pending prepared statements.

db.close();

Database.exec(sql)

Executes the given SQL string. The SQL string may contain several semicolon-separated statements.

db.exec(
  "DROP TABLE IF EXISTS book; CREATE TABLE book (id INTEGER PRIMARY KEY, title TEXT)"
);

Database.function(name, func, [options]) -> this

Registers a user-defined function.

Arguments

  • name: the name of the function
  • func: the implementation of the function
  • options (optional)
    • deterministic (default: false): if true, the function is considered deterministic
db.function("regexp", (y, x) => new RegExp(y, "i").test(x), {
  deterministic: true,
});
db.all("SELECT * FROM book WHERE title REGEXP ?", ".*little.*");

Database.get(sql, [values, options]) -> row

Creates a prepared statement, executes it with the given values and returns the first resulting row as an object. The prepared statement is finalized automatically.

Arguments

  • sql: string containing the SQL statement
  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
  • options (optional)
    • expand (default: false): if true, the returned row is a nested object with keys corresponding to tables in the query. If a result column is an expression or subquery, it will be returned under the key $.
db.get("SELECT * FROM book WHERE id = ?", 7);
db.get("SELECT * FROM book WHERE id = $id", { $id: 7 });
db.get("SELECT * FROM book WHERE id = ? AND title = ?", [
  3,
  "The Little Prince",
]);

Database.prepare(sql) -> Statement

Creates a prepared statement from the given SQL string.

Important: You have to manually finalize a statement, otherwise you risk memory leaks. See Statement and, in particular, Statement.finalize().

const stmt = db.prepare("INSERT INTO book (title) VALUES (?)");
try {
  // do something with the statement here
} finally {
  stmt.finalize();
}

The Database class provides the convenience methods

These convenience methods use a prepared statement internally and take care of finalizing it.

Database.run(sql, [values]) -> info

Creates a prepared statement, executes it with the given values and returns an object with the properties changes and lastInsertRowid describing the number of modified rows and the id of the last row inserted. lastInsertRowid is a BigInt if its value exceeds Number.MAX_SAFE_INTEGER. The prepared statement is finalized automatically.

Arguments

  • sql: string containing the SQL statement
  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
db.run("INSERT INTO book (title) VALUES (?)", "The Little Prince");
db.run("INSERT INTO book VALUES (?, ?)", [10, "The Little Prince"]);
db.run("INSERT INTO book VALUES (@id, :title)", {
  "@id": 10,
  ":title": "The Little Prince",
});

Database.inTransaction

Property determining whether the database is currently in a transaction.

const stmt = db.prepare("INSERT INTO book (title) VALUES (?)");
try {
  db.exec("BEGIN TRANSACTION");
  stmt.run("The Little Prince");
  stmt.run("The Hobbit");
  db.exec("COMMIT");
} catch (err) {
  if (db.inTransaction) db.exec("ROLLBACK");
  console.log(err);
} finally {
  stmt.finalize();
}

Database.isOpen

Property determining whether the database is currently open.

class Statement

Methods

Properties

Important: You have to manually finalize a statement, otherwise you risk memory leaks (see Statement.finalize()).

const stmt = db.prepare("SELECT * FROM book WHERE id = ?");
try {
  // do something with the statement here
} finally {
  stmt.finalize();
}

As an alternative, the Database class provides the convenience methods

These convenience methods use a prepared statement internally and take care of finalizing it.

Statement.all([values, options]) -> rows

Executes the prepared statement with the given values and returns the resulting rows as an array of objects.

Arguments

  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
  • options (optional)
    • expand (default: false): if true, each returned row is a nested object with keys corresponding to tables in the query. If a result column is an expression or subquery, it will be returned under the key $.

See also Database.all()

Statement.finalize()

Finalizes the statement and frees all allocated memory. Once a statement has been finalized, it cannot be used anymore.

Important: You have to manually finalize a statement, otherwise you risk memory leaks.

Important: Closing the database with Database.close() does not automatically finalize pending prepared statements.

Statement.get([values, options]) -> row

Executes the prepared statement with the given values and returns the first resulting row as an object.

Arguments

  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
  • options (optional)
    • expand (default: false): if true, the returned row is a nested object with keys corresponding to tables in the query. If a result column is an expression or subquery, it will be returned under the key $.

See also Database.get()

Statement.iterate([values, options]) -> IterableIterator<row>

Executes the prepared statement with the given values and returns the resulting rows as an iterator of objects.

Arguments

  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.
  • options (optional)
    • expand (default: false): if true, each returned row is a nested object with keys corresponding to tables in the query. If a result column is an expression or subquery, it will be returned under the key $.

Statement.run([values]) -> info

Executes the prepared statement with the given values and returns an object with the properties changes and lastInsertRowid describing the number of modified rows and the id of the last row inserted. lastInsertRowid is a BigInt if its value exceeds Number.MAX_SAFE_INTEGER.

Arguments

  • values (optional): values to bind to the statement's parameters. Either a single value, an array, or an object in case of named parameters.

See also Database.run()

Statement.database

The Database object that instantiated this statement.

Statement.isFinalized

Property determining whether the statement has been finalized using Statement.finalize(). A finalized statement must not be used anymore.

class SQLite3Error

node-sqlite3-wasm throws an SQLite3Error whenever an error in SQLite or in the API occurs. SQLite3Error is a subclass of Error.

Notes About Types

Numbers

JavaScript's Number type is a double-precision 64-bit binary format IEEE 754 value. Integers can only be represented without loss of precision in the range -253 + 1 to 253 - 1, inclusive. SQLite3 works with 8-byte signed integers with a range of -263 to 263 - 1, inclusive. Since this range exceeds the range of safe integers in JavaScript, node-sqlite3-wasm automatically converts integers outside this safe range to BigInt. It is your responsibility to ensure that you handle the returned values, whether Number or BigInt, correctly. node-sqlite3-wasm also allows you to input BigInt values as query parameters, or arguments or return values of user-defined functions.

Binary Large Objects (BLOBs)

An SQLite Binary Large Object (BLOB) is represented by a Uint8Array in JavaScript.

Building

Docker and npm are required for building. Mocha is required to run tests.

To build node-sqlite3-wasm, simply run

npm run build

This will download the emscripten Docker image and the SQLite source files. Then it will compile the project source files and generate dist/node-sqlite3-wasm.js and dist/node-sqlite3-wasm.wasm.

License

node-sqlite3-wasm is MIT licensed.

Parts of the code are from sql.js, which is also MIT licensed. SQLite is in the public domain.