refactor withOperations

Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
Andrey Platov 2021-08-05 09:23:13 +02:00
parent cb68860a93
commit 1a1639108b
No known key found for this signature in database
GPG Key ID: C8787EFEB4B64AF0
4 changed files with 74 additions and 74 deletions

View File

@ -17,13 +17,13 @@
import { Space } from '../classes'
import { createClient } from '../client'
import core from '../component'
import { withOperations } from '../tx'
import { TxOperations } from '../tx'
import { connect } from './connection'
describe('client', () => {
it('client', async () => {
const klass = core.class.Space
const client = withOperations(core.account.System, await createClient(connect))
const client = new TxOperations(await createClient(connect), core.account.System)
const result = await client.findAll(klass, {})
expect(result).toHaveLength(2)

View File

@ -18,7 +18,7 @@ import core from '../component'
import { Hierarchy } from '../hierarchy'
import { ModelDb, TxDb } from '../memdb'
import { SortingOrder } from '../storage'
import { withOperations } from '../tx'
import { TxOperations } from '../tx'
import { genMinModel } from './minmodel'
const txes = genMinModel()
@ -52,7 +52,7 @@ describe('memdb', () => {
const result = await model.findAll(core.class.Space, {})
expect(result.length).toBe(2)
const ops = withOperations(core.account.System, model)
const ops = new TxOperations(model, core.account.System)
await ops.removeDoc(result[0]._class, result[0].space, result[0]._id)
const result2 = await model.findAll(core.class.Space, {})
expect(result2).toHaveLength(1)
@ -122,7 +122,7 @@ describe('memdb', () => {
it('should push to array', async () => {
const hierarchy = new Hierarchy()
for (const tx of txes) await hierarchy.tx(tx)
const model = withOperations(core.account.System, new ModelDb(hierarchy))
const model = new TxOperations(new ModelDb(hierarchy), core.account.System)
for (const tx of txes) await model.tx(tx)
const space = await model.createDoc(core.class.Space, core.space.Model, {
name: 'name',
@ -131,15 +131,15 @@ describe('memdb', () => {
members: []
})
const account = await model.createDoc(core.class.Account, core.space.Model, {})
await model.updateDoc(core.class.Space, core.space.Model, space._id, { $push: { members: account._id } })
const txSpace = await model.findAll(core.class.Space, { _id: space._id })
expect(txSpace[0].members).toEqual(expect.arrayContaining([account._id]))
await model.updateDoc(core.class.Space, core.space.Model, space, { $push: { members: account } })
const txSpace = await model.findAll(core.class.Space, { _id: space })
expect(txSpace[0].members).toEqual(expect.arrayContaining([account]))
})
it('limit and sorting', async () => {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
const model = withOperations(core.account.System, new ModelDb(hierarchy))
const model = new TxOperations(new ModelDb(hierarchy), core.account.System)
for (const tx of txes) await model.tx(tx)
const without = await model.findAll(core.class.Space, {})

View File

@ -15,14 +15,10 @@
import type { KeysByType } from 'simplytyped'
import type { Class, Data, Doc, Domain, Ref, Account, Space, Arr, Mixin } from './classes'
import { DocumentQuery, FindOptions, FindResult, Storage } from './storage'
import core from './component'
import { generateId } from './utils'
// export interface TxFactory {
// createTxCreateDoc: <T extends Doc>(_class: Ref<Class<T>>, space: Ref<Space>, attributes: Data<T>) => TxCreateDoc<T>
// createTxMixin: <D extends Doc, M extends D>(objectId: Ref<D>, objectClass: Ref<Class<D>>, mixin: Ref<Mixin<M>>, attributes: ExtendedAttributes<D, M>) => TxMixin<D, M>
// }
/**
* @public
*/
@ -139,82 +135,49 @@ export class TxProcessor implements WithTx {
/**
* @public
*/
export interface TxOperations {
createDoc: <T extends Doc>(_class: Ref<Class<T>>, space: Ref<Space>, attributes: Data<T>) => Promise<T>
updateDoc: <T extends Doc>(
_class: Ref<Class<T>>,
space: Ref<Space>,
objectId: Ref<T>,
operations: DocumentUpdate<T>
) => Promise<void>
removeDoc: <T extends Doc>(_class: Ref<Class<T>>, space: Ref<Space>, objectId: Ref<T>) => Promise<void>
}
export class TxOperations implements Storage {
private readonly txFactory: TxFactory
/**
* @public
*/
export function withOperations<T extends WithTx> (user: Ref<Account>, storage: T): T & TxOperations {
const result = storage as T & TxOperations
constructor (private readonly storage: Storage, user: Ref<Account>) {
this.txFactory = new TxFactory(user)
}
result.createDoc = async <T extends Doc>(
findAll <T extends Doc>(_class: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T> | undefined): Promise<FindResult<T>> {
return this.storage.findAll(_class, query, options)
}
tx (tx: Tx<Doc>): Promise<void> {
return this.storage.tx(tx)
}
async createDoc<T extends Doc> (
_class: Ref<Class<T>>,
space: Ref<Space>,
attributes: Data<T>
): Promise<T> => {
const tx: TxCreateDoc<T> = {
_id: generateId(),
_class: core.class.TxCreateDoc,
space: core.space.Tx,
modifiedBy: user,
modifiedOn: Date.now(),
objectId: generateId(),
objectClass: _class,
objectSpace: space,
attributes
}
await storage.tx(tx)
return TxProcessor.createDoc2Doc(tx)
): Promise<Ref<T>> {
const tx = this.txFactory.createTxCreateDoc(_class, space, attributes)
await this.storage.tx(tx)
return tx.objectId
}
result.updateDoc = async <T extends Doc>(
updateDoc <T extends Doc>(
_class: Ref<Class<T>>,
space: Ref<Space>,
objectId: Ref<T>,
operations: DocumentUpdate<T>
): Promise<void> => {
const tx: TxUpdateDoc<T> = {
_id: generateId(),
_class: core.class.TxUpdateDoc,
space: core.space.Tx,
modifiedBy: user,
modifiedOn: Date.now(),
objectId,
objectClass: _class,
objectSpace: space,
operations
}
await storage.tx(tx)
): Promise<void> {
const tx = this.txFactory.createTxUpdateDoc(_class, space, objectId, operations)
return this.storage.tx(tx)
}
result.removeDoc = async <T extends Doc>(
removeDoc<T extends Doc> (
_class: Ref<Class<T>>,
space: Ref<Space>,
objectId: Ref<T>
): Promise<void> => {
const tx: TxRemoveDoc<T> = {
_id: generateId(),
_class: core.class.TxRemoveDoc,
space: core.space.Tx,
modifiedBy: user,
modifiedOn: Date.now(),
objectId,
objectClass: _class,
objectSpace: space
}
await storage.tx(tx)
): Promise<void> {
const tx = this.txFactory.createTxRemoveDoc(_class, space, objectId)
return this.storage.tx(tx)
}
return result
}
/**
@ -237,6 +200,42 @@ export class TxFactory {
}
}
createTxUpdateDoc <T extends Doc>(
_class: Ref<Class<T>>,
space: Ref<Space>,
objectId: Ref<T>,
operations: DocumentUpdate<T>
): TxUpdateDoc<T> {
return {
_id: generateId(),
_class: core.class.TxUpdateDoc,
space: core.space.Tx,
modifiedBy: this.account,
modifiedOn: Date.now(),
objectId,
objectClass: _class,
objectSpace: space,
operations
}
}
createTxRemoveDoc<T extends Doc> (
_class: Ref<Class<T>>,
space: Ref<Space>,
objectId: Ref<T>
): TxRemoveDoc<T> {
return {
_id: generateId(),
_class: core.class.TxRemoveDoc,
space: core.space.Tx,
modifiedBy: this.account,
modifiedOn: Date.now(),
objectId,
objectClass: _class,
objectSpace: space
}
}
createTxMixin<D extends Doc, M extends D>(objectId: Ref<D>, objectClass: Ref<Class<D>>, mixin: Ref<Mixin<M>>, attributes: ExtendedAttributes<D, M>): TxMixin<D, M> {
return {
_id: generateId(),

View File

@ -3,6 +3,7 @@
"standard-with-typescript"
],
"rules": {
"@typescript-eslint/array-type": "off"
"@typescript-eslint/array-type": "off",
"@typescript-eslint/promise-function-async": "off"
}
}