Skip to main content

SQLite persistence

Use a SQLite database to store your structured data persistently.

Root supports your use of a SQLite database:

  • Providing the database filename.
  • Backing up and restoring the database file automatically so you won't lose data if your server restarts.

Storage limit​

Each app or bot instance has limited space for its SQLite database. Keep your database under 500 MB.

How to use it​

You need to add a few dependencies to your package.json file:

  • Dependency on sqlite3 to get the database engine into your server code.
  • Dependency on your choice of access libraries.

In addition, you use the Root-provided database filename at: rootServer.dataStore.config.sqlite3.filename in your initialization code. You must use this filename, so Root knows where your data is stored and can do automated backups for you.

Library options for SQLite access​

You can use any library you prefer to access SQLite. There are three main types of libraries:

CategoryWhat it doesExamples
Direct librariesExecute raw SQL statements yourself.sqlite3, sqlite
Query buildersBuild SQL queries programmatically.Knex, Kysely
ORMsWork with objects; the library generates SQL for you.Prisma, TypeORM

Root recommends you build an upload package early during your development to test how large your preferred database-access library is; some of them add quite a bit of content to your code.

Example: sqlite3​

Here's an example using sqlite3. The sqlite3 library and database engine are packaged together; if you use this library for access, then you don't need to install any additional packages.

import { rootServer } from '@rootsdk/server-app';
import { Database } from "sqlite3";

const db = new Database(rootServer.dataStore.config.sqlite3!.filename);

db.serialize(() =>
{
db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)");
db.run("INSERT INTO users (name, email) VALUES (?, ?)", ["Bob", "[email protected]"]);
});

db.close();

Example: Knex​

Here's an example using Knex (you'd need to add the Knex package as a dependency in your package.json):

import { rootServer } from '@rootsdk/server-app';
import Knex from "knex";

const knex = Knex(
{
client: "sqlite3",
connection: { filename: rootServer.dataStore.config.sqlite3!.filename },
useNullAsDefault: true
});

await knex.schema.createTable("users", (table) =>
{
table.increments("id").primary();
table.string("name");
table.string("email");
});

await knex("users").insert({ name: "bob", email: "[email protected]" });

Example: Sequelize​

Here's an example using Sequelize (you'd need to add the Sequelize package as a dependency in your package.json):

import { rootServer } from '@rootsdk/server-app';
import { Sequelize } from "sequelize";

const sequelize = new Sequelize(
{
dialect: "sqlite",
storage: rootServer.dataStore.config.sqlite3!.filename
});

const User = sequelize.define("User",
{
name: { type: Sequelize.STRING },
email: { type: Sequelize.STRING }
});

await sequelize.sync();
await User.create({ name: "Bob", email: "[email protected]" });

Example: Sequelize-typescript​

Here's an example using Sequelize-typescript (you'd need to add the Sequelize-typescript and Sequelize packages as dependencies in your package.json):

import { rootServer } from '@rootsdk/server-app';
import { Sequelize } from "sequelize-typescript";
import { Table, Column, Model, DataType } from "sequelize-typescript";

const sequelize = new Sequelize
({
dialect: "sqlite",
storage: rootServer.dataStore.config.sqlite3!.filename,
models: [User]
});

@Table({ tableName: "users" })
class User extends Model
{
@Column({ type: DataType.STRING, allowNull: false })
name!: string;

@Column({ type: DataType.STRING, allowNull: false })
email!: string;
}

async function setupDatabase()
{
await sequelize.sync();
await User.create({ name: "Alice", email: "[email protected]" });
}