UNPKG

indinis

Version:

A storage library using LSM trees for storage and B-trees for indices with MVCC support

123 lines (111 loc) 4.36 kB
// tssrc/batch-api.ts import { Indinis } from './index'; import { ItemRef, StoreRef } from './fluent-api'; import { AtomicIncrementOperation, BatchOperation, BatchOperationType } from './types'; /** * A temporary reference to a document used only for building a batch operation. * It exposes the core write methods, but instead of executing them, it queues * them in the parent BatchWriter. * @internal */ export class BatchItemRef<T extends { id?: string }> { constructor( private readonly batchWriter: BatchWriter, private readonly fullPath: string ) {} /** * Queues a 'create' or 'overwrite' operation for this document in the batch. * @param data The data for the document. * @param overwrite If false (default), the transaction will fail if the document exists. If true, it overwrites. * @returns The parent BatchWriter instance for further chaining. */ make(data: Omit<T, 'id'>, overwrite: boolean = false): BatchWriter { (this.batchWriter as any)._addOperation({ op: BatchOperationType.MAKE, key: this.fullPath, value: data, overwrite: overwrite, }); return this.batchWriter; } /** * Queues a 'modify' (merge and/or atomic) operation for this document in the batch. * @param data An object containing fields to update, including atomic increments. * @returns The parent BatchWriter instance for further chaining. */ modify(data: Partial<{ [K in keyof T]: T[K] | AtomicIncrementOperation }>): BatchWriter { (this.batchWriter as any)._addOperation({ op: BatchOperationType.MODIFY, key: this.fullPath, value: data, }); return this.batchWriter; } /** * Queues a 'delete' operation for this document in the batch. * @returns The parent BatchWriter instance for further chaining. */ remove(): BatchWriter { (this.batchWriter as any)._addOperation({ op: BatchOperationType.REMOVE, key: this.fullPath, }); return this.batchWriter; } } /** * A temporary reference to a store path used only for building a batch. * @internal */ export class BatchStoreRef<T extends { id?: string }> { constructor( private readonly batchWriter: BatchWriter, public readonly storePath: string, ) {} /** * Gets a reference to a document within this store to add a batch operation. * @param itemId The ID of the document. * @returns A BatchItemRef instance for specifying the write operation. */ item(itemId: string): BatchItemRef<T> { const fullPath = `${this.storePath}/${itemId}`; return new BatchItemRef<T>(this.batchWriter, fullPath); } } /** * The main batch writer class. It collects operations and sends them to the * native C++ engine for atomic execution upon calling .commit(). */ export class BatchWriter { private operations: BatchOperation[] = []; /** @internal */ constructor(private readonly db: Indinis) {} /** * Gets a reference to a store path to begin chaining batch operations. * @param storePath The path to the collection (e.g., 'users'). * @returns A BatchStoreRef instance. */ public store<T extends { id?: string }>(storePath: string): BatchStoreRef<T> { return new BatchStoreRef<T>(this, storePath); } /** @internal - Used by BatchItemRef to add an operation. */ public _addOperation(op: BatchOperation): void { this.operations.push(op); } /** * Commits all queued operations to the database atomically. * @returns A promise that resolves when the commit is successful. */ public async commit(): Promise<void> { if (this.operations.length === 0) { // No-op, resolve immediately. return Promise.resolve(); } const engine = (this.db as any).getNativeEngine(); if (!engine) { throw new Error("Indinis engine is not initialized or has been closed."); } // This will call the new N-API binding. await engine.commitBatch_internal(this.operations); } }