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

best-sqlite3

v1.0.19

Published

A JS-native driver for SQLite3 with middleware for storing Express Sessions included

Downloads

64

Readme

best-sqlite3

What is SQLite3?

SQLite, version 3, is an RDBMS - relational database management system written in C.

It differs from most other systems (MySQL, Postgre etc) in that there is not a separate server running the database, instead the SQLite code gets embedded in the application you are writing.

SQLite stores a whole database in one single file.

If you want a graphical editor for SQLite we recommend SQLiteStudio - cross platform, with a nice GUI.

Note: The SQL dialect spoken by SQLite is similar to the syntax in PostgreSQL and rather similar to MySQL/MariaDB. An important difference compared to MySQL/MariaDB is that you can not use && instead of AND or || instead of OR. Just get used to writing AND and OR!

What is best-sqlite3?

  • best-sqlite3 is a driver that lets you run SQLite3 with Node.js.
  • It differs from other Node.js drivers in that it does not need node-gyp or any binaries during installation, because it runs SQLite3 recompiled to JavaScript/webassembly (thanks to the SQL.js project)
  • best-sqlite3 provides a simple API and guarantees you that you won't run into problems with compiling bindings to other languages - the npm installation will be trouble free regardless of your operating system, Node.js version etc.
  • best-sqlite3 is quite fast. See the tests below comparing it to the drivers sqlite3 and better-sqlite3.

Also:

  • best-sqlite3 includes middleware for creating an Express Session store, with which you can store Express-sessions in your SQLite3 database, making them survive server restarts.

Installation

npm i best-sqlite3

Basic usage

Require best-sqlite3 and connect to a database, then run queries.

(async () => { // start of async wrapper

  // Require bestSqlite
  const bestSqlite = require('best-sqlite3');

  // Connect to a database
  // (if the file does not exist 
  //  a new db will be created)
  const db = await bestSqlite
    .connect('path-to-db-file.sqlite3');

  // Run a query
  let allUsers = db.run(`
    SELECT * FROM users
  `);

  // Run a query with parameters
  // (a prepared statement)
  let allJanes = db.run(
    `
      SELECT * FROM users
      WHERE firstName = $firstName
    `, 
    {
      firstName: 'Jane'
    }
  );


})().catch(e => console.error(e)); 
// end of async wrapper

What does the run-method return?

  • For SELECT-queries run will return an array of objects. Each object corresponds to a row in the database.
  • For other statements (CREATE, INSERT, UPDATE, DELETE) run returns an object with the property rowsModified (number of rows modified)
  • For INSERT statements the property lastInsertRowId (the id of the latest row inserted) is also provided.

User defined functions with the regFunc-method

You can define your own functions written in JavaScript that you can then use in your SQL-queries.

// Register a function
db.regFunc('concatWithSpace', (x, y) => x + ' ' + y);

// Use the function in your query
db.run(`
  SELECT concatWithSpace(firstName, lastName) AS fullName
  FROM users
`);

Lists tables and views in a database

You can easily get a list (array of strings) with the names of the tables in a database. The same goes for all the views in a database...

// db.tables - a list of all tables in the database
console.log(db.tables);

// db.views - a list of all views in the database
console.log(db.views);

Storing express-session sessions in the database

The npm module express-session is used to get user sessions based on cookies to work with express (the popular web server for Node.js).

By default express-session stores session in internal memory, but its documentation recommend against doing so in production.

best-sqlite3 provides middleware that can be used together with express-session to automatically store sessions in the database instead.

(async () => { // start of async wrapper

  const express = require('express');
  const session = require('express-session');
  const bestSqlite = require('best-sqlite3');

  const app = express();
  const db = await bestSqlite.connect('path-to-db-file.sqlite3');

  // Setting up the express session middleware
  // with bestSqlite as a store
  app.use(session({
    secret: 'your own secret',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: 'auto' },
    // tell express session to use our bestSqlite connection
    // (this will store the sessions in the database)
    store: db.sessionStore(
      // Optional settings
      {
        // What table to store sessions in
        tableName: 'sessions', 
        // Minutes a session lives after inactivity
        deleteAfterInactivityMinutes: 120
      }
    )
  }));

  // Check that storing sessions in the db works 
  // (restart your app/server to see that 
  //  the urls are still remembered)
  app.get('*', (req, res) => {
    let { visited } = req.session;
    if (!visited) { visited = req.session.visited = []; }
    req.url !== '/favicon.ico' && visited.push(req.url);
    res.send('Visited urls:<br>' + visited.join('<br>'));
  });

  app.listen(3000, () => console.log('Listening on port 3000!'));

})().catch(e => console.error(e)); 
// end of async wrapper

Scaling to multiple processes - what about concurrency?

To save time best-sqlite3 only writes changes to file when there are no queries in queue.

This approach works well as long as you only have one Node.js process communicating with a database. So if you are starting out - learning Node.js and SQLite, writing smaller apps - you will be just fine!

But: If your application has grown to a stage where you need to load-balance it by running several copies of your app in a cluster, you might get into trouble if the order in which you run destructive operations (insert, update, delete) is crucial.

We are currently working on a stand alone server version that will fix this. This server will run as a separate process on a separate port and handle all direct communication with the file system. Individual queries will run slower but will take no CPU-time from your application. The api-syntax will be identical, apart from having to write await before method calls, for example await run instead of run.