import { DocumentUpdate, Hierarchy, MixinData, MixinUpdate, ModelDb } from '.' import type { Account, AttachedData, AttachedDoc, Class, Data, Doc, Mixin, PropertyType, Ref, Space } from './classes' import { Client } from './client' import core from './component' import type { DocumentQuery, FindOptions, FindResult, TxResult, WithLookup } from './storage' import { Tx, TxFactory } from './tx' /** * @public * * High Level operations with client, will create low level transactions. * * `notify` is not supported by TxOperations. */ export class TxOperations implements Omit { readonly txFactory: TxFactory constructor (protected readonly client: Client, user: Ref) { this.txFactory = new TxFactory(user) } getHierarchy (): Hierarchy { return this.client.getHierarchy() } getModel (): ModelDb { return this.client.getModel() } async close (): Promise { return await this.client.close() } findAll( _class: Ref>, query: DocumentQuery, options?: FindOptions | undefined ): Promise> { return this.client.findAll(_class, query, options) } findOne( _class: Ref>, query: DocumentQuery, options?: FindOptions | undefined ): Promise | undefined> { return this.client.findOne(_class, query, options) } tx (tx: Tx): Promise { return this.client.tx(tx) } async createDoc( _class: Ref>, space: Ref, attributes: Data, id?: Ref ): Promise> { const tx = this.txFactory.createTxCreateDoc(_class, space, attributes, id) await this.client.tx(tx) return tx.objectId } async addCollection( _class: Ref>, space: Ref, attachedTo: Ref, attachedToClass: Ref>, collection: string, attributes: AttachedData

, id?: Ref

): Promise> { const tx = this.txFactory.createTxCollectionCUD( attachedToClass, attachedTo, space, collection, this.txFactory.createTxCreateDoc

(_class, space, attributes as unknown as Data

, id) ) await this.client.tx(tx) return tx.tx.objectId as unknown as Ref

} async updateCollection( _class: Ref>, space: Ref, objectId: Ref

, attachedTo: Ref, attachedToClass: Ref>, collection: string, operations: DocumentUpdate

, retrieve?: boolean ): Promise> { const tx = this.txFactory.createTxCollectionCUD( attachedToClass, attachedTo, space, collection, this.txFactory.createTxUpdateDoc(_class, space, objectId, operations, retrieve) ) await this.client.tx(tx) return tx.objectId } async removeCollection( _class: Ref>, space: Ref, objectId: Ref

, attachedTo: Ref, attachedToClass: Ref>, collection: string ): Promise> { const tx = this.txFactory.createTxCollectionCUD( attachedToClass, attachedTo, space, collection, this.txFactory.createTxRemoveDoc(_class, space, objectId) ) await this.client.tx(tx) return tx.objectId } putBag

( _class: Ref>, space: Ref, objectId: Ref, bag: string, key: string, value: P ): Promise { const tx = this.txFactory.createTxPutBag(_class, space, objectId, bag, key, value) return this.client.tx(tx) } updateDoc( _class: Ref>, space: Ref, objectId: Ref, operations: DocumentUpdate, retrieve?: boolean ): Promise { const tx = this.txFactory.createTxUpdateDoc(_class, space, objectId, operations, retrieve) return this.client.tx(tx) } removeDoc(_class: Ref>, space: Ref, objectId: Ref): Promise { const tx = this.txFactory.createTxRemoveDoc(_class, space, objectId) return this.client.tx(tx) } createMixin( objectId: Ref, objectClass: Ref>, objectSpace: Ref, mixin: Ref>, attributes: MixinData ): Promise { const tx = this.txFactory.createTxMixin(objectId, objectClass, objectSpace, mixin, attributes) return this.client.tx(tx) } updateMixin( objectId: Ref, objectClass: Ref>, objectSpace: Ref, mixin: Ref>, attributes: MixinUpdate ): Promise { const tx = this.txFactory.createTxMixin(objectId, objectClass, objectSpace, mixin, attributes) return this.client.tx(tx) } update(doc: T, update: DocumentUpdate, retrieve?: boolean): Promise { if (this.client.getHierarchy().isDerived(doc._class, core.class.AttachedDoc)) { const adoc = doc as unknown as AttachedDoc return this.updateCollection( doc._class, doc.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection, update, retrieve ) } return this.updateDoc(doc._class, doc.space, doc._id, update, retrieve) } remove(doc: T): Promise { if (this.client.getHierarchy().isDerived(doc._class, core.class.AttachedDoc)) { const adoc = doc as unknown as AttachedDoc return this.removeCollection( doc._class, doc.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection ) } return this.removeDoc(doc._class, doc.space, doc._id) } }