[]
        
(Showing Draft Content)

데이터베이스 어댑터

데이터베이스 어댑터(IDatabaseAdapter)는 서버 측 기능의 핵심 요소로, 문서 스냅샷과 작업(operation)의 영구 저장을 담당합니다.

데이터베이스 어댑터는 기본 저장소와의 상호작용 방식을 정의합니다. 작업(op)은 이력 기록을 위해 지속적으로 저장되며, 스냅샷은 누적된 작업에 의해 업데이트되는 최신 버전만 유지합니다.

이 문서는 데이터베이스 어댑터를 사용하고 구현하는 방법과 이를 DocumentServices에 통합하는 방법을 설명합니다.

  • 문서 스냅샷과 작업 저장 및 읽기

  • 이력 데이터 조회 및 작업 제출 지원

적용 시나리오: 프로덕션 환경에서의 영구 저장, 사용자 지정 저장소 솔루션

기본 제공 어댑터: MemoryDb(인메모리 저장소), Postgres 어댑터, SQLite3 어댑터

인터페이스: IDatabaseAdapter

/**
 * OT(Operational Transformation)에서 데이터베이스 어댑터를 정의하는 인터페이스.
 * @template S - 스냅샷 데이터 타입.
 * @template T - 작업(operation) 데이터 타입.
 * @public
 */
export interface IDatabaseAdapter<S = unknown, T = unknown> {
    /**
     * 두 버전 사이의 작업을 조회합니다('from' 포함, 'to' 미포함).
     * @param {string} id - 문서 ID.
     * @param {number} from - 시작 버전.
     * @param {number} [to] - 종료 버전(선택).
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<IOp<T>[]>} 작업 배열을 반환하는 Promise.
     */
    getOps(id: string, from: number, to?: number, options?: unknown): Promise<IOp<T>[]>;
    /**
     * ID로 문서 정보를 조회합니다.
     * @param {string} id - 문서 ID.
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<IDocument | null>} 문서 정보 또는 없을 경우 null을 반환하는 Promise.
     */
    getDocument(id: string, options?: unknown): Promise<IDocument | null>;

    /**
     * ID로 문서 스냅샷을 조회합니다.
     * @param {string} id - 문서 ID.
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<ISnapshot<S> | null>} 스냅샷 또는 없을 경우 null을 반환하는 Promise.
     */
    getSnapshot(id: string, options?: unknown): Promise<ISnapshot<S> | null>;
    /**
     * ID로 문서의 특정 프래그먼트를 조회합니다.
     * @param {string} id - 문서 ID.
     * @param {string} fragmentId - 프래그먼트 ID.
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<{ version: number, data: S | null } | null>}
     * 문서가 존재하면 프래그먼트 버전과 데이터를 포함한 객체를 반환하고,
     * 문서가 없으면 null을 반환합니다.
     * 문서는 존재하지만 프래그먼트가 없으면 data는 null입니다.
     */
    getFragment(id: string, fragmentId: string, options?: unknown): Promise<{ version: number, data: S | null } | null>;

    /**
     * 작업을 데이터베이스에 커밋합니다.
     * @param {string} id - 문서 ID.
     * @param {IOp<T>} op - 커밋할 작업.
     * @param {IDocument} document - 문서 메타데이터.
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<boolean>} 커밋 성공 시 true, 실패 시 false를 반환하는 Promise.
     */
    commitOp(id: string, op: IOp<T>, document: IDocument, options?: unknown): Promise<boolean>;
    /**
     * 스냅샷을 데이터베이스에 커밋합니다.
     * @param {string} id - 문서 ID.
     * @param {ICommitSnapshot<S>} snapshot - 커밋할 스냅샷.
     * @param {unknown} [options] - 추가 옵션(선택).
     * @returns {Promise<boolean>} 커밋 성공 시 true, 실패 시 false를 반환하는 Promise.
     */
    commitSnapshot(id: string, snapshot: ICommitSnapshot<S>, options?: unknown): Promise<boolean>;

    /**
     * 이미 커밋된 작업의 버전을 조회합니다(존재하는 경우).
     * @param {string} id - 문서 ID.
     * @param {number} to - 확인할 종료 버전.
     * @param {IOp<T>} op - 검증할 작업.
     * @returns {Promise<number | null>} 커밋된 버전 또는 없을 경우 null을 반환하는 Promise.
     */
    getCommittedOpVersion(id: string, to: number, op: IOp): Promise<number | null>;

    /**
     * 데이터베이스 연결을 종료합니다.
     * @returns {Promise<void>} 데이터베이스가 닫히면 완료되는 Promise.
     */
    close(): Promise<void>;
}

DocumentServices에 통합

데이터베이스 어댑터를 DocumentServices의 구성에 전달합니다.

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

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

기본 제공 어댑터

MemoryDb

  • 설명: RAM에 데이터를 저장하는 인메모리 어댑터

  • 사용 사례: 개발 및 테스트

  • 제한 사항: 서버 재시작 시 데이터가 손실되며, 프로덕션 환경에는 적합하지 않음

  • 참고: DocumentServices 생성 시 MemoryDb가 기본 데이터베이스 어댑터로 사용됩니다.

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

const dbAdapter = new MemoryDb();

Postgres 데이터베이스 어댑터

  • 설명: PostgreSQL 기반의 영구 저장 어댑터

  • 사용 사례: 영구 저장이 필요한 프로덕션 환경

  • 스키마

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, // 기본 포트
};
const dbInstance = new pg.Pool(config);
const dbAdapter = new PostgresDb(dbInstance);

Sqlite3 데이터베이스 어댑터

  • 설명: SQLite3 기반의 영구 저장 어댑터

  • 사용 사례: 영구 저장을 지원하는 개발 및 테스트 환경

  • 스키마

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

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

사용자 정의 데이터베이스 어댑터 구현

기본 제공 어댑터가 요구 사항을 충족하지 못하는 경우, IDatabaseAdapter 인터페이스를 구현하여 사용자 정의 데이터베이스 어댑터를 만들 수 있습니다. 자세한 내용은 사용자 정의 데이터베이스 어댑터를 참고하세요.