// // Copyright © 2022 Hardcore Engineering Inc. // // Licensed under the Eclipse Public License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // limitations under the License. // import { Class, Doc, DocumentQuery, DocumentUpdate, Domain, FindOptions, FindResult, Hierarchy, IndexingConfiguration, ModelDb, Ref, StorageIterator, toFindResult, Tx, TxResult, WorkspaceId } from '@hcengineering/core' import { MinioService } from '@hcengineering/minio' /** * @public */ export interface DbAdapter { /** * Method called after hierarchy is ready to use. */ init: (model: Tx[]) => Promise createIndexes: (domain: Domain, config: Pick, 'indexes'>) => Promise close: () => Promise findAll: ( _class: Ref>, query: DocumentQuery, options?: FindOptions ) => Promise> tx: (...tx: Tx[]) => Promise find: (domain: Domain) => StorageIterator load: (domain: Domain, docs: Ref[]) => Promise upload: (domain: Domain, docs: Doc[]) => Promise clean: (domain: Domain, docs: Ref[]) => Promise // Bulk update operations update: (domain: Domain, operations: Map, DocumentUpdate>) => Promise } /** * @public */ export interface TxAdapter extends DbAdapter { getModel: () => Promise } /** * @public */ export type DbAdapterFactory = ( hierarchy: Hierarchy, url: string, workspaceId: WorkspaceId, modelDb: ModelDb, storage?: MinioService ) => Promise /** * @public */ export interface DbAdapterConfiguration { factory: DbAdapterFactory url: string } /** * @public */ export class DummyDbAdapter implements DbAdapter { async init (model: Tx[]): Promise {} async findAll( _class: Ref>, query: DocumentQuery, options?: FindOptions | undefined ): Promise> { return toFindResult([]) } async createIndexes (domain: Domain, config: Pick, 'indexes'>): Promise {} async tx (...tx: Tx[]): Promise { return {} } async close (): Promise {} find (domain: Domain): StorageIterator { return { next: async () => undefined, close: async () => {} } } async load (domain: Domain, docs: Ref[]): Promise { return [] } async upload (domain: Domain, docs: Doc[]): Promise {} async clean (domain: Domain, docs: Ref[]): Promise {} async update (domain: Domain, operations: Map, DocumentUpdate>): Promise {} } class InMemoryAdapter extends DummyDbAdapter implements DbAdapter { private readonly modeldb: ModelDb constructor (hierarchy: Hierarchy) { super() this.modeldb = new ModelDb(hierarchy) } async findAll( _class: Ref>, query: DocumentQuery, options?: FindOptions ): Promise> { return await this.modeldb.findAll(_class, query, options) } async tx (...tx: Tx[]): Promise { return await this.modeldb.tx(...tx) } async init (model: Tx[]): Promise { for (const tx of model) { try { await this.modeldb.tx(tx) } catch (err: any) { console.error('skip broken TX', err) } } } } /** * @public */ export async function createInMemoryAdapter ( hierarchy: Hierarchy, url: string, workspaceId: WorkspaceId ): Promise { return new InMemoryAdapter(hierarchy) }