[]
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
/**
* 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>;
}
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 });
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();
Description: A persistent adapter based on PostgreSQL.
Use Case: Production environments, supporting persistent storage.
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);
Description: A persistent adapter based on SQLite3.
Use Case: Development and testing environments, supporting persistent storage.
import sqlite3 from 'sqlite3';
import { SqliteDb } from '@mescius/js-collaboration-ot-sqlite';
const dbInstance = new sqlite3.Database("./sample.db");
const dbAdapter = new SqliteDb(dbInstance);
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.