[]
        
(Showing Draft Content)

Database Adapter

The database adapter (IDatabaseAdapter) is a key point of the server-side functionality, responsible for the persistent storage of document snapshots and operations.

The database adapter defines the interaction with the underlying storage. Operations (op) are continuously stored to record history, while snapshots only retain the latest version, updated by accumulated operations.

This document explains how to use and implement a database adapter and integrate it into DocumentServices.

  • Store and read document snapshots and operations

  • Support historical data queries and submissions

Applicable Scenarios: Persistent storage in production environments, custom storage solutions

Built-in Adapters: MemoryDb (in-memory storage), Postgres Adapter, and SQLite3 Adapter

Interface: IDatabaseAdapter

/**
 * The database adapter interface.
 */
export interface IDatabaseAdapter<S = unknown, T = unknown> {
    /**
     * Get the ops between two versions, include from version, exclude to version.
     */
    getOps(id: string, from: number, to?: number, options?: unknown): Promise<IOp<T>[]>;
    /**
     * Get the document info by id.
     */
    getDocument(id: string, options?: unknown): Promise<IDocument | undefined | null>;
    /**
     * Get the snapshot by id.
     */
    getSnapshot(id: string, options?: unknown): Promise<ISnapshot<S> | undefined | null>;
    getFragment(id: string, fragmentId: string, options?: unknown): Promise<S | undefined | null>;
    getFragments(id: string, fragmentIds?: string[], options?: unknown): Promise<{ [id: string]: S }>;
    commitOp(id: string, op: IOp<T>, document: IDocument, options?: unknown): Promise<boolean>;
    commitSnapshot(id: string, snapshot: ICommitSnapshot<S>, options?: unknown): Promise<boolean>;
    /**
     * Get the committed op version, if the op is committed, return the committed version, otherwise return undefined.
     */
    getCommittedOpVersion(id: string, to: number, op: IOp): Promise<number | undefined>;
    /**
     * Close the database.
     */
    close(): Promise<void>;
}

Integration into DocumentServices

Pass the database adapter into the configuration of DocumentServices:

import { DocumentServices, IDatabaseAdapter, MemoryDb } from '@mescius/js-collaboration-ot';

const dbAdapter: IDatabaseAdapter = new MemoryDb();
const docService = new DocumentServices({ db: dbAdapter });

Built-in Adapters

MemoryDb

  • Description: An in-memory adapter, with data stored in RAM.

  • Use Case: Development and testing.

  • Limitations: Data is lost after the server restarts, not suitable for production environments.

import { MemoryDb } from '@mescius/js-collaboration-ot';

const dbAdapter = new MemoryDb();

Postgres Database Adapter

  • Description: A persistent adapter based on PostgreSQL.

  • Use Case: Production environments, supporting persistent storage.

  • Schema

import pg from 'pg';
import { PostgresDb } from '@mescius/js-collaboration-ot-postgres';

const config = {
    host: 'localhost',
    database: 'your_database',
    user: 'your_user_name',
    password: 'your_password',
    port: 5432, // default port
};
const dbInstance = new pg.Pool(config);
const dbAdapter = new PostgresDb(dbInstance);

Sqlite3 Database Adapter

  • Description: A persistent adapter based on SQLite3.

  • Use Case: Development and testing environments, supporting persistent storage.

  • Schema

import sqlite3 from 'sqlite3';
import { SqliteDb } from '@mescius/js-collaboration-ot-sqlite';

const dbInstance = new sqlite3.Database("./sample.db");
const dbAdapter = new SqliteDb(dbInstance);

Implementing a Custom Database Adapter

If the built-in adapters do not meet your needs, you can create a custom database adapter by implementing the IDatabaseAdapter interface. Please refer to Custom Database Adapter.