Realm

Table of Contents

  1. Overview
  2. Constructor Options
    1. Models as Directory Path
    2. Models as Array
  3. Connecting
    1. realm.connect()
    2. realm.disconnect()
  4. Using connect() Shortcut
  5. Defining Models Dynamically
    1. realm.define(name, attributes, options, descriptors)
  6. Schema Synchronization
    1. realm.sync(options)
  7. Raw Queries
    1. realm.query(sql, values, options)
    2. realm.raw(sql)
    3. realm.escape(value)
  8. Transactions
    1. realm.transaction(callback)
  9. Multiple Database Instances
  10. Properties

Overview

Realm is the central entry point of Leoric. It manages the database connection, model registration, schema synchronization, and provides methods for raw queries and transactions.

import Realm from 'leoric';

const realm = new Realm({
  dialect: 'mysql',
  host: 'localhost',
  user: 'root',
  database: 'my_app',
  models: 'app/models',
});

await realm.connect();

Constructor Options

The Realm constructor accepts a configuration object with the following options:

Option Type Default Description
dialect string 'mysql' Database dialect: 'mysql', 'postgres', or 'sqlite'
client string β€” Client module name: 'mysql', 'mysql2', 'pg', 'sqlite3', '@journeyapps/sqlcipher'
dialectModulePath string β€” Alias for client
host string β€” Database host
port number \| string β€” Database port
user string β€” Database user
password string β€” Database password
database string β€” Database name (aliases: db, storage)
models Array \| string β€” An array of model classes, or a directory path string
subclass boolean false Whether to create a subclass of Bone to isolate models
driver AbstractDriver β€” Custom driver class
define object β€” Default model define options, e.g. { underscored: true }
logger object β€” Custom logger, see Logging
charset string β€” Database charset
idleTimeout number β€” Connection idle timeout in milliseconds
sequelize boolean false Enable Sequelize compatibility adapter
skipCloneValue boolean false Skip cloning attribute values for performance (v2.14+)

Models as Directory Path

When models is a string, Leoric will scan the directory and load all .js, .mjs, and .ts files that export a Bone subclass:

const realm = new Realm({
  dialect: 'mysql',
  host: 'localhost',
  database: 'my_app',
  models: 'app/models', // scans this directory
});

Models as Array

You can also pass model classes directly:

import Post from './models/post';
import User from './models/user';

const realm = new Realm({
  dialect: 'mysql',
  host: 'localhost',
  database: 'my_app',
  models: [Post, User],
});

Connecting

realm.connect()

Connect to the database and initialize all models. This method loads schema information from the database and maps it to the registered models.

await realm.connect();
// Models are now ready to use
const posts = await Post.find();

realm.disconnect()

Disconnect from the database and release the connection pool.

await realm.disconnect();

You can also pass a callback that will be executed before releasing connections:

await realm.disconnect(async () => {
  console.log('Cleaning up...');
});

Using connect() Shortcut

For simple use cases, you can use the connect() function exported from leoric directly, without creating a Realm instance explicitly:

import { Bone, connect } from 'leoric';

class Post extends Bone {}

await connect({
  host: 'localhost',
  database: 'my_app',
  models: [Post],
});

// Post is now ready
const posts = await Post.find();

Note: connect() can only be called once with the default Bone. If you need multiple connections, use separate Realm instances.

Defining Models Dynamically

realm.define(name, attributes, options, descriptors)

Define a model dynamically at runtime without creating a separate class file.

const { BIGINT, STRING, TEXT } = realm.DataTypes;

const Post = realm.define('Post', {
  id: { type: BIGINT, primaryKey: true },
  title: STRING,
  content: TEXT,
});

await realm.sync();

// Now you can use the model
await Post.create({ title: 'Hello', content: 'World' });

Parameters:

Parameter Type Description
name string Model name (will be used to infer table name)
attributes object Column definitions
options object Optional model init options
descriptors object Optional property descriptors

Schema Synchronization

realm.sync(options)

Synchronize the model definitions to the database. This will create tables that don’t exist, and optionally alter existing tables to match the model definitions.

await realm.sync();

Options:

Option Type Default Description
force boolean false Drop existing tables before creating (destructive!)
alter boolean false Alter existing tables to match model definitions
// Create tables that don't exist
await realm.sync();

// Drop and recreate all tables (WARNING: data loss!)
await realm.sync({ force: true });

// Alter existing tables to match models
await realm.sync({ alter: true });

Warning: realm.sync({ force: true }) will drop all existing tables. Use with extreme caution, and never in production!

Raw Queries

realm.query(sql, values, options)

Execute a raw SQL query against the database.

const result = await realm.query('SELECT * FROM posts WHERE id = ?', [1]);
console.log(result.rows); // => [{ id: 1, title: '...', ... }]

See Raw Queries for more details.

realm.raw(sql)

Create a Raw SQL expression that won’t be escaped.

await Post.update({ title: 'New Title' }, {
  updatedAt: realm.raw('NOW()'),
});

realm.escape(value)

Escape a value for safe use in SQL queries.

const safe = realm.escape("O'Reilly");
// => "'O\\'Reilly'"

Transactions

realm.transaction(callback)

Start a transaction. The callback receives a { connection } object that can be used to ensure all queries within the transaction use the same connection.

await realm.transaction(async ({ connection }) => {
  await Post.create({ title: 'Hello' }, { connection });
  await Comment.create({ postId: 1, content: 'World' }, { connection });
});

See Transactions for more details.

Multiple Database Instances

You can create multiple Realm instances to connect to different databases:

const realmA = new Realm({
  dialect: 'mysql',
  database: 'app_primary',
  models: [User, Post],
  subclass: true, // isolate models
});

const realmB = new Realm({
  dialect: 'postgres',
  database: 'app_analytics',
  models: [Event, Metric],
  subclass: true, // isolate models
});

await realmA.connect();
await realmB.connect();

Important: When using multiple Realm instances, set subclass: true to ensure models from different realms don’t share the same Bone base class internals.

Properties

Property Type Description
realm.Bone class The base model class for this realm
realm.models object Map of registered model names to classes
realm.driver object The database driver instance
realm.connected boolean Whether the realm is connected
realm.DataTypes object Data type constructors