mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 11:31:57 +03:00
TxCollectionCUD
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
8ef4b49800
commit
b6fac06d2b
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type { IntlString } from '@anticrm/platform'
|
import type { IntlString } from '@anticrm/platform'
|
||||||
import type { Account, AnyAttribute, Class, ClassifierKind, Doc, Domain, Mixin, Obj, Ref, Space, Timestamp, Type } from '@anticrm/core'
|
import type { Account, AnyAttribute, AttachedDoc, Class, ClassifierKind, Doc, Domain, Mixin, Obj, Ref, Space, Timestamp, Type } from '@anticrm/core'
|
||||||
import { DOMAIN_MODEL } from '@anticrm/core'
|
import { DOMAIN_MODEL } from '@anticrm/core'
|
||||||
import { Model, Prop, TypeTimestamp } from '@anticrm/model'
|
import { Model, Prop, TypeTimestamp } from '@anticrm/model'
|
||||||
import core from './component'
|
import core from './component'
|
||||||
@ -36,6 +36,12 @@ export class TDoc extends TObj implements Doc {
|
|||||||
modifiedBy!: Ref<Account>
|
modifiedBy!: Ref<Account>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Model(core.class.AttachedDoc, core.class.Doc)
|
||||||
|
export class TAttachedDoc extends TDoc implements AttachedDoc {
|
||||||
|
attachedTo!: Ref<Doc>
|
||||||
|
attachedToClass!: Ref<Class<Doc>>
|
||||||
|
}
|
||||||
|
|
||||||
@Model(core.class.Class, core.class.Doc, DOMAIN_MODEL)
|
@Model(core.class.Class, core.class.Doc, DOMAIN_MODEL)
|
||||||
export class TClass extends TDoc implements Class<Obj> {
|
export class TClass extends TDoc implements Class<Obj> {
|
||||||
kind!: ClassifierKind
|
kind!: ClassifierKind
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
|
|
||||||
import { Builder } from '@anticrm/model'
|
import { Builder } from '@anticrm/model'
|
||||||
import core from './component'
|
import core from './component'
|
||||||
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString, TTypeBoolean, TTypeTimestamp } from './core'
|
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString, TTypeBoolean, TTypeTimestamp, TAttachedDoc } from './core'
|
||||||
import { TSpace, TAccount, TState, TSpaceWithStates, TDocWithState } from './security'
|
import { TSpace, TAccount, TState, TSpaceWithStates, TDocWithState } from './security'
|
||||||
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag, TTxRemoveDoc, TTxBulkWrite, TTxAddCollection } from './tx'
|
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag, TTxRemoveDoc, TTxBulkWrite, TTxCollectionCUD } from './tx'
|
||||||
|
|
||||||
export * from './core'
|
export * from './core'
|
||||||
export * from './security'
|
export * from './security'
|
||||||
@ -33,7 +33,8 @@ export function createModel (builder: Builder): void {
|
|||||||
TTx,
|
TTx,
|
||||||
TTxCUD,
|
TTxCUD,
|
||||||
TTxCreateDoc,
|
TTxCreateDoc,
|
||||||
TTxAddCollection,
|
TAttachedDoc,
|
||||||
|
TTxCollectionCUD,
|
||||||
TTxPutBag,
|
TTxPutBag,
|
||||||
TTxMixin,
|
TTxMixin,
|
||||||
TTxUpdateDoc,
|
TTxUpdateDoc,
|
||||||
|
@ -14,25 +14,25 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
AttachedDoc,
|
||||||
Class,
|
Class,
|
||||||
Data,
|
Data,
|
||||||
Doc,
|
Doc,
|
||||||
DocumentUpdate,
|
DocumentUpdate,
|
||||||
|
ExtendedAttributes,
|
||||||
|
Mixin,
|
||||||
|
PropertyType,
|
||||||
Ref,
|
Ref,
|
||||||
Space,
|
Space,
|
||||||
Tx,
|
Tx,
|
||||||
TxCUD,
|
|
||||||
TxCreateDoc,
|
|
||||||
TxRemoveDoc,
|
|
||||||
TxUpdateDoc,
|
|
||||||
TxMixin,
|
|
||||||
Mixin,
|
|
||||||
ExtendedAttributes,
|
|
||||||
PropertyType,
|
|
||||||
TxPutBag,
|
|
||||||
TxBulkWrite,
|
TxBulkWrite,
|
||||||
AttachedDoc,
|
TxCollectionCUD,
|
||||||
TxAddCollection
|
TxCreateDoc,
|
||||||
|
TxCUD,
|
||||||
|
TxMixin,
|
||||||
|
TxPutBag,
|
||||||
|
TxRemoveDoc,
|
||||||
|
TxUpdateDoc
|
||||||
} from '@anticrm/core'
|
} from '@anticrm/core'
|
||||||
import { DOMAIN_TX } from '@anticrm/core'
|
import { DOMAIN_TX } from '@anticrm/core'
|
||||||
import { Model } from '@anticrm/model'
|
import { Model } from '@anticrm/model'
|
||||||
@ -57,11 +57,10 @@ export class TTxCreateDoc<T extends Doc> extends TTxCUD<T> implements TxCreateDo
|
|||||||
attributes!: Data<T>
|
attributes!: Data<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(core.class.TxAddCollection, core.class.TxCreateDoc)
|
@Model(core.class.TxCollectionCUD, core.class.TxCUD)
|
||||||
export class TTxAddCollection<T extends AttachedDoc> extends TTxCreateDoc<T> implements TxAddCollection<T> {
|
export class TTxCollectionCUD<T extends Doc, P extends AttachedDoc> extends TTxCUD<T> implements TxCollectionCUD<T, P> {
|
||||||
collection!: string
|
collection!: string
|
||||||
attachedTo!: Ref<Doc>
|
tx!: TxCUD<P>
|
||||||
attachedToClass!: Ref<Class<Doc>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Model(core.class.TxPutBag, core.class.TxCUD)
|
@Model(core.class.TxPutBag, core.class.TxCUD)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Class, Obj, Ref } from '../classes'
|
import type { Class, Obj, Ref, Doc } from '../classes'
|
||||||
import core from '../component'
|
import core from '../component'
|
||||||
import { Hierarchy } from '../hierarchy'
|
import { Hierarchy } from '../hierarchy'
|
||||||
import { ModelDb, TxDb } from '../memdb'
|
import { ModelDb, TxDb } from '../memdb'
|
||||||
@ -23,24 +23,37 @@ import { genMinModel, test, TestMixin } from './minmodel'
|
|||||||
|
|
||||||
const txes = genMinModel()
|
const txes = genMinModel()
|
||||||
|
|
||||||
async function createModel (): Promise<{ model: ModelDb, hierarchy: Hierarchy }> {
|
async function createModel (): Promise<{ model: ModelDb, hierarchy: Hierarchy, txDb: TxDb }> {
|
||||||
const hierarchy = new Hierarchy()
|
const hierarchy = new Hierarchy()
|
||||||
for (const tx of txes) hierarchy.tx(tx)
|
for (const tx of txes) {
|
||||||
|
hierarchy.tx(tx)
|
||||||
|
}
|
||||||
const model = new ModelDb(hierarchy)
|
const model = new ModelDb(hierarchy)
|
||||||
for (const tx of txes) await model.tx(tx)
|
for (const tx of txes) {
|
||||||
return { model, hierarchy }
|
await model.tx(tx)
|
||||||
|
}
|
||||||
|
const txDb = new TxDb(hierarchy)
|
||||||
|
for (const tx of txes) await txDb.tx(tx)
|
||||||
|
return { model, hierarchy, txDb }
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('memdb', () => {
|
describe('memdb', () => {
|
||||||
it('should save all tx', async () => {
|
it('should save all tx', async () => {
|
||||||
const hierarchy = new Hierarchy()
|
const { txDb } = await createModel()
|
||||||
for (const tx of txes) hierarchy.tx(tx)
|
|
||||||
const txDb = new TxDb(hierarchy)
|
|
||||||
for (const tx of txes) await txDb.tx(tx)
|
|
||||||
const result = await txDb.findAll(core.class.Tx, {})
|
const result = await txDb.findAll(core.class.Tx, {})
|
||||||
expect(result.length).toBe(txes.filter((tx) => tx._class === core.class.TxCreateDoc).length)
|
expect(result.length).toBe(txes.filter((tx) => tx._class === core.class.TxCreateDoc).length)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should query model', async () => {
|
||||||
|
const { model } = await createModel()
|
||||||
|
|
||||||
|
const result = await model.findAll(core.class.Class, {})
|
||||||
|
expect(result.length).toBeGreaterThan(5)
|
||||||
|
const result2 = await model.findAll('class:workbench.Application' as Ref<Class<Doc>>, { _id: undefined })
|
||||||
|
expect(result2).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
it('should create space', async () => {
|
it('should create space', async () => {
|
||||||
const { model } = await createModel()
|
const { model } = await createModel()
|
||||||
|
|
||||||
@ -65,7 +78,8 @@ describe('memdb', () => {
|
|||||||
it('should query model', async () => {
|
it('should query model', async () => {
|
||||||
const { model } = await createModel()
|
const { model } = await createModel()
|
||||||
const result = await model.findAll(core.class.Class, {})
|
const result = await model.findAll(core.class.Class, {})
|
||||||
expect(result.length).toBe(10)
|
const names = result.map(d => d._id)
|
||||||
|
expect(names.includes(core.class.Class)).toBe(true)
|
||||||
const result2 = await model.findAll(core.class.Class, { _id: undefined })
|
const result2 = await model.findAll(core.class.Class, { _id: undefined })
|
||||||
expect(result2.length).toBe(0)
|
expect(result2.length).toBe(0)
|
||||||
})
|
})
|
||||||
@ -103,10 +117,7 @@ describe('memdb', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should query model with params', async () => {
|
it('should query model with params', async () => {
|
||||||
const hierarchy = new Hierarchy()
|
const { model } = await createModel()
|
||||||
for (const tx of txes) hierarchy.tx(tx)
|
|
||||||
const model = new ModelDb(hierarchy)
|
|
||||||
for (const tx of txes) await model.tx(tx)
|
|
||||||
const first = await model.findAll(core.class.Class, {
|
const first = await model.findAll(core.class.Class, {
|
||||||
_id: txes[1].objectId as Ref<Class<Obj>>,
|
_id: txes[1].objectId as Ref<Class<Obj>>,
|
||||||
kind: 0
|
kind: 0
|
||||||
@ -132,10 +143,7 @@ describe('memdb', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should query model like params', async () => {
|
it('should query model like params', async () => {
|
||||||
const hierarchy = new Hierarchy()
|
const { model } = await createModel()
|
||||||
for (const tx of txes) hierarchy.tx(tx)
|
|
||||||
const model = new ModelDb(hierarchy)
|
|
||||||
for (const tx of txes) await model.tx(tx)
|
|
||||||
const expectedLength = txes.filter((tx) => tx.objectSpace === core.space.Model).length
|
const expectedLength = txes.filter((tx) => tx.objectSpace === core.space.Model).length
|
||||||
const without = await model.findAll(core.class.Doc, {
|
const without = await model.findAll(core.class.Doc, {
|
||||||
space: { $like: core.space.Model }
|
space: { $like: core.space.Model }
|
||||||
@ -205,34 +213,17 @@ describe('memdb', () => {
|
|||||||
expect(numberSort[0].modifiedOn).toBeLessThanOrEqual(numberSort[numberSortDesc.length - 1].modifiedOn)
|
expect(numberSort[0].modifiedOn).toBeLessThanOrEqual(numberSort[numberSortDesc.length - 1].modifiedOn)
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('should throw error', async () => {
|
it('should add attached document', async () => {
|
||||||
// expect.assertions(1)
|
const { model } = await createModel()
|
||||||
// const errorTx: TxAddCollection<Doc, Emb> = {
|
|
||||||
// _id: '60b73133d22498e666800cd2' as Ref<TxAddCollection<Doc, Emb>>,
|
|
||||||
// _class: 'class:core.TxAddCollection' as Ref<Class<TxAddCollection<Doc, Emb>>>,
|
|
||||||
// space: core.space.Tx,
|
|
||||||
// modifiedBy: 'xxx' as Ref<Account>,
|
|
||||||
// modifiedOn: 0,
|
|
||||||
// objectId: 'class:test.MyClass' as Ref<Doc>,
|
|
||||||
// objectSpace: core.space.Model,
|
|
||||||
// itemClass: 'class:core.Attribute' as Ref<Class<Doc>>,
|
|
||||||
// collection: 'attributes',
|
|
||||||
// localId: 'name',
|
|
||||||
// attributes: {
|
|
||||||
// _class: 'class:core.Attribute' as Ref<Class<Doc>>,
|
|
||||||
// // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
||||||
// __embedded: {
|
|
||||||
// _class: 'class:core.Attribute' as Ref<Class<Doc>>
|
|
||||||
// } as Emb
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const hierarchy = new Hierarchy()
|
const client = new TxOperations(model, core.account.System)
|
||||||
// for (const tx of txes) hierarchy.tx(tx)
|
const result = await client.findAll(core.class.Space, {})
|
||||||
// const model = new ModelDb(hierarchy)
|
expect(result).toHaveLength(2)
|
||||||
|
|
||||||
// await model.tx(errorTx).catch((error: Error) => {
|
await client.addCollection(test.class.TestComment, core.space.Model, result[0]._id, result[0]._class, 'comments', {
|
||||||
// expect(error.message).toBe('ERROR: status:core.ObjectNotFound')
|
message: 'msg'
|
||||||
// })
|
})
|
||||||
// })
|
const result2 = await client.findAll(test.class.TestComment, {})
|
||||||
|
expect(result2).toHaveLength(1)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Plugin, IntlString } from '@anticrm/platform'
|
import type { IntlString, Plugin } from '@anticrm/platform'
|
||||||
import { plugin } from '@anticrm/platform'
|
import { plugin } from '@anticrm/platform'
|
||||||
import type { Class, Data, Doc, Obj, Ref, Mixin, Arr } from '../classes'
|
import type { Arr, Class, Data, Doc, Mixin, Obj, Ref } from '../classes'
|
||||||
import { ClassifierKind, DOMAIN_MODEL } from '../classes'
|
import { AttachedDoc, ClassifierKind, DOMAIN_MODEL } from '../classes'
|
||||||
import type { TxCUD, TxCreateDoc } from '../tx'
|
|
||||||
import core from '../component'
|
import core from '../component'
|
||||||
|
import type { TxCreateDoc, TxCUD } from '../tx'
|
||||||
import { DOMAIN_TX, TxFactory } from '../tx'
|
import { DOMAIN_TX, TxFactory } from '../tx'
|
||||||
|
|
||||||
const txFactory = new TxFactory(core.account.System)
|
const txFactory = new TxFactory(core.account.System)
|
||||||
@ -35,9 +35,16 @@ export interface TestMixin extends Doc {
|
|||||||
arr: Arr<string>
|
arr: Arr<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttachedComment extends AttachedDoc {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
export const test = plugin('test' as Plugin, {
|
export const test = plugin('test' as Plugin, {
|
||||||
mixin: {
|
mixin: {
|
||||||
TestMixin: '' as Ref<Mixin<TestMixin>>
|
TestMixin: '' as Ref<Mixin<TestMixin>>
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
TestComment: '' as Ref<Class<AttachedComment>>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -50,17 +57,22 @@ export function genMinModel (): TxCUD<Doc>[] {
|
|||||||
// Fill Tx'es with basic model classes.
|
// Fill Tx'es with basic model classes.
|
||||||
txes.push(createClass(core.class.Obj, { label: 'Obj' as IntlString, kind: ClassifierKind.CLASS }))
|
txes.push(createClass(core.class.Obj, { label: 'Obj' as IntlString, kind: ClassifierKind.CLASS }))
|
||||||
txes.push(createClass(core.class.Doc, { label: 'Doc' as IntlString, extends: core.class.Obj, kind: ClassifierKind.CLASS }))
|
txes.push(createClass(core.class.Doc, { label: 'Doc' as IntlString, extends: core.class.Obj, kind: ClassifierKind.CLASS }))
|
||||||
|
txes.push(createClass(core.class.AttachedDoc, { label: 'AttachedDoc' as IntlString, extends: core.class.Doc, kind: ClassifierKind.MIXIN }))
|
||||||
txes.push(createClass(core.class.Class, { label: 'Class' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
txes.push(createClass(core.class.Class, { label: 'Class' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
||||||
txes.push(createClass(core.class.Space, { label: 'Space' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
txes.push(createClass(core.class.Space, { label: 'Space' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
||||||
txes.push(createClass(core.class.Account, { label: 'Account' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
txes.push(createClass(core.class.Account, { label: 'Account' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
|
||||||
|
|
||||||
txes.push(createClass(core.class.Tx, { label: 'Tx' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_TX }))
|
txes.push(createClass(core.class.Tx, { label: 'Tx' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_TX }))
|
||||||
txes.push(createClass(core.class.TxCreateDoc, { label: 'TxCreateDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
|
txes.push(createClass(core.class.TxCUD, { label: 'TxCUD' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS, domain: DOMAIN_TX }))
|
||||||
txes.push(createClass(core.class.TxUpdateDoc, { label: 'TxUpdateDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
|
txes.push(createClass(core.class.TxCreateDoc, { label: 'TxCreateDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
|
||||||
txes.push(createClass(core.class.TxRemoveDoc, { label: 'TxRemoveDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
|
txes.push(createClass(core.class.TxUpdateDoc, { label: 'TxUpdateDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
|
||||||
|
txes.push(createClass(core.class.TxRemoveDoc, { label: 'TxRemoveDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
|
||||||
|
txes.push(createClass(core.class.TxCollectionCUD, { label: 'TxCollectionCUD' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
|
||||||
|
|
||||||
txes.push(createClass(test.mixin.TestMixin, { label: 'TestMixin' as IntlString, extends: core.class.Doc, kind: ClassifierKind.MIXIN }))
|
txes.push(createClass(test.mixin.TestMixin, { label: 'TestMixin' as IntlString, extends: core.class.Doc, kind: ClassifierKind.MIXIN }))
|
||||||
|
|
||||||
|
txes.push(createClass(test.class.TestComment, { label: 'TestComment' as IntlString, extends: core.class.AttachedDoc, kind: ClassifierKind.CLASS }))
|
||||||
|
|
||||||
txes.push(
|
txes.push(
|
||||||
createDoc(core.class.Space, {
|
createDoc(core.class.Space, {
|
||||||
name: 'Sp1',
|
name: 'Sp1',
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
import type { Plugin, StatusCode } from '@anticrm/platform'
|
import type { Plugin, StatusCode } from '@anticrm/platform'
|
||||||
import { plugin } from '@anticrm/platform'
|
import { plugin } from '@anticrm/platform'
|
||||||
import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute, State, Type, PropertyType, SpaceWithStates, Timestamp, DocWithState, AttachedDoc } from './classes'
|
import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute, State, Type, PropertyType, SpaceWithStates, Timestamp, DocWithState, AttachedDoc } from './classes'
|
||||||
import type { Tx, TxAddCollection, TxBulkWrite, TxCreateDoc, TxCUD, TxMixin, TxPutBag, TxRemoveDoc, TxUpdateDoc } from './tx'
|
import type { Tx, TxCollectionCUD, TxBulkWrite, TxCreateDoc, TxCUD, TxMixin, TxPutBag, TxRemoveDoc, TxUpdateDoc } from './tx'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -26,13 +26,14 @@ export default plugin(coreId, {
|
|||||||
class: {
|
class: {
|
||||||
Obj: '' as Ref<Class<Obj>>,
|
Obj: '' as Ref<Class<Obj>>,
|
||||||
Doc: '' as Ref<Class<Doc>>,
|
Doc: '' as Ref<Class<Doc>>,
|
||||||
|
AttachedDoc: '' as Ref<Class<AttachedDoc>>,
|
||||||
Class: '' as Ref<Class<Class<Obj>>>,
|
Class: '' as Ref<Class<Class<Obj>>>,
|
||||||
Attribute: '' as Ref<Class<AnyAttribute>>,
|
Attribute: '' as Ref<Class<AnyAttribute>>,
|
||||||
Tx: '' as Ref<Class<Tx>>,
|
Tx: '' as Ref<Class<Tx>>,
|
||||||
TxBulkWrite: '' as Ref<Class<TxBulkWrite>>,
|
TxBulkWrite: '' as Ref<Class<TxBulkWrite>>,
|
||||||
TxCUD: '' as Ref<Class<TxCUD<Doc>>>,
|
TxCUD: '' as Ref<Class<TxCUD<Doc>>>,
|
||||||
TxCreateDoc: '' as Ref<Class<TxCreateDoc<Doc>>>,
|
TxCreateDoc: '' as Ref<Class<TxCreateDoc<Doc>>>,
|
||||||
TxAddCollection: '' as Ref<Class<TxAddCollection<AttachedDoc>>>,
|
TxCollectionCUD: '' as Ref<Class<TxCollectionCUD<Doc, AttachedDoc>>>,
|
||||||
TxMixin: '' as Ref<Class<TxMixin<Doc, Doc>>>,
|
TxMixin: '' as Ref<Class<TxMixin<Doc, Doc>>>,
|
||||||
TxUpdateDoc: '' as Ref<Class<TxUpdateDoc<Doc>>>,
|
TxUpdateDoc: '' as Ref<Class<TxUpdateDoc<Doc>>>,
|
||||||
TxRemoveDoc: '' as Ref<Class<TxRemoveDoc<Doc>>>,
|
TxRemoveDoc: '' as Ref<Class<TxRemoveDoc<Doc>>>,
|
||||||
|
@ -42,12 +42,14 @@ export interface TxCreateDoc<T extends Doc> extends TxCUD<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* Will perform create/update/delete of attached documents.
|
||||||
|
*
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface TxAddCollection<T extends AttachedDoc> extends TxCreateDoc<T> {
|
export interface TxCollectionCUD<T extends Doc, P extends AttachedDoc> extends TxCUD<T> {
|
||||||
collection: string
|
collection: string
|
||||||
attachedTo: Ref<Doc>
|
tx: TxCUD<P>
|
||||||
attachedToClass: Ref<Class<Doc>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,8 +195,8 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
switch (tx._class) {
|
switch (tx._class) {
|
||||||
case core.class.TxCreateDoc:
|
case core.class.TxCreateDoc:
|
||||||
return await this.txCreateDoc(tx as TxCreateDoc<Doc>)
|
return await this.txCreateDoc(tx as TxCreateDoc<Doc>)
|
||||||
case core.class.TxAddCollection:
|
case core.class.TxCollectionCUD:
|
||||||
return await this.txAddCollection(tx as TxAddCollection<AttachedDoc>)
|
return await this.txCollectionCUD(tx as TxCollectionCUD<Doc, AttachedDoc>)
|
||||||
case core.class.TxUpdateDoc:
|
case core.class.TxUpdateDoc:
|
||||||
return await this.txUpdateDoc(tx as TxUpdateDoc<Doc>)
|
return await this.txUpdateDoc(tx as TxUpdateDoc<Doc>)
|
||||||
case core.class.TxRemoveDoc:
|
case core.class.TxRemoveDoc:
|
||||||
@ -209,7 +211,7 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
throw new Error('TxProcessor: unhandled transaction class: ' + tx._class)
|
throw new Error('TxProcessor: unhandled transaction class: ' + tx._class)
|
||||||
}
|
}
|
||||||
|
|
||||||
static createDoc2Doc<T extends Doc> (tx: TxCreateDoc<T>): T {
|
static createDoc2Doc<T extends Doc>(tx: TxCreateDoc<T>): T {
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
return {
|
return {
|
||||||
_id: tx.objectId,
|
_id: tx.objectId,
|
||||||
@ -227,15 +229,25 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
protected abstract txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult>
|
protected abstract txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult>
|
||||||
protected abstract txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult>
|
protected abstract txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult>
|
||||||
|
|
||||||
protected txAddCollection (tx: TxAddCollection<AttachedDoc>): Promise<TxResult> {
|
protected txCollectionCUD (tx: TxCollectionCUD<Doc, AttachedDoc>): Promise<TxResult> {
|
||||||
const createTx: TxCreateDoc<Doc> = { ...tx }
|
// We need update only create transactions to contain attached, attachedToClass.
|
||||||
createTx.attributes = { ...tx.attributes, attachedTo: tx.attachedTo, attachedToClass: tx.attachedToClass }
|
if (tx.tx._class === core.class.TxCreateDoc) {
|
||||||
return this.txCreateDoc(createTx)
|
const createTx = tx.tx as TxCreateDoc<AttachedDoc>
|
||||||
|
const d: TxCreateDoc<AttachedDoc> = {
|
||||||
|
...createTx,
|
||||||
|
attributes: {
|
||||||
|
...createTx.attributes,
|
||||||
|
attachedTo: tx.objectId,
|
||||||
|
attachedToClass: tx.objectClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.txCreateDoc(d)
|
||||||
|
}
|
||||||
|
return this.tx(tx.tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async txBulkWrite (bulkTx: TxBulkWrite): Promise<TxResult> {
|
protected async txBulkWrite (bulkTx: TxBulkWrite): Promise<TxResult> {
|
||||||
for (const tx of bulkTx.txes) {
|
for (const tx of bulkTx.txes) {
|
||||||
console.log('bulk', tx)
|
|
||||||
await this.tx(tx)
|
await this.tx(tx)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
@ -275,16 +287,42 @@ export class TxOperations implements Storage {
|
|||||||
return tx.objectId
|
return tx.objectId
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCollection<T extends AttachedDoc> (
|
async addCollection<T extends Doc, P extends AttachedDoc>(
|
||||||
_class: Ref<Class<T>>,
|
_class: Ref<Class<P>>,
|
||||||
space: Ref<Space>,
|
space: Ref<Space>,
|
||||||
attachedTo: Ref<Doc>,
|
attachedTo: Ref<T>,
|
||||||
attachedToClass: Ref<Class<Doc>>,
|
attachedToClass: Ref<Class<T>>,
|
||||||
collection: string,
|
collection: string,
|
||||||
attributes: AttachedData<T>,
|
attributes: AttachedData<P>,
|
||||||
id?: Ref<T>
|
id?: Ref<P>
|
||||||
): Promise<Ref<T>> {
|
): Promise<Ref<T>> {
|
||||||
const tx = this.txFactory.createTxAddCollection(_class, space, attributes, attachedTo, attachedToClass, collection, id)
|
const tx = this.txFactory.createTxCollectionCUD<T, P>(
|
||||||
|
attachedToClass,
|
||||||
|
attachedTo,
|
||||||
|
space,
|
||||||
|
collection,
|
||||||
|
this.txFactory.createTxCreateDoc<P>(_class, space, attributes as unknown as Data<P>, id)
|
||||||
|
)
|
||||||
|
await this.storage.tx(tx)
|
||||||
|
return tx.objectId
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCollection<T extends Doc, P extends AttachedDoc>(
|
||||||
|
_class: Ref<Class<P>>,
|
||||||
|
space: Ref<Space>,
|
||||||
|
attachedTo: Ref<T>,
|
||||||
|
attachedToClass: Ref<Class<T>>,
|
||||||
|
collection: string,
|
||||||
|
objectId: Ref<P>,
|
||||||
|
operations: DocumentUpdate<P>
|
||||||
|
): Promise<Ref<T>> {
|
||||||
|
const tx = this.txFactory.createTxCollectionCUD(
|
||||||
|
attachedToClass,
|
||||||
|
attachedTo,
|
||||||
|
space,
|
||||||
|
collection,
|
||||||
|
this.txFactory.createTxUpdateDoc(_class, space, objectId, operations)
|
||||||
|
)
|
||||||
await this.storage.tx(tx)
|
await this.storage.tx(tx)
|
||||||
return tx.objectId
|
return tx.objectId
|
||||||
}
|
}
|
||||||
@ -352,20 +390,24 @@ export class TxFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createTxAddCollection<T extends AttachedDoc>(_class: Ref<Class<T>>, space: Ref<Space>, attributes: AttachedData<T>, attachedTo: Ref<Doc>, attachedToClass: Ref<Class<Doc>>, collection: string, objectId?: Ref<T>): TxAddCollection<T> {
|
createTxCollectionCUD<T extends Doc, P extends AttachedDoc>(
|
||||||
|
_class: Ref<Class<T>>,
|
||||||
|
objectId: Ref<T>,
|
||||||
|
space: Ref<Space>,
|
||||||
|
collection: string,
|
||||||
|
tx: TxCUD<P>
|
||||||
|
): TxCollectionCUD<T, P> {
|
||||||
return {
|
return {
|
||||||
_id: generateId(),
|
_id: generateId(),
|
||||||
_class: core.class.TxAddCollection,
|
_class: core.class.TxCollectionCUD,
|
||||||
space: core.space.Tx,
|
space: core.space.Tx,
|
||||||
objectId: objectId ?? generateId(),
|
objectId,
|
||||||
objectClass: _class,
|
objectClass: _class,
|
||||||
objectSpace: space,
|
objectSpace: space,
|
||||||
modifiedOn: Date.now(),
|
modifiedOn: Date.now(),
|
||||||
modifiedBy: this.account,
|
modifiedBy: this.account,
|
||||||
attributes: attributes as Data<T>,
|
|
||||||
collection,
|
collection,
|
||||||
attachedTo,
|
tx
|
||||||
attachedToClass
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class } from '@anticrm/core'
|
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
|
||||||
import type { FindAll } from '@anticrm/server-core'
|
import type { FindAll } from '@anticrm/server-core'
|
||||||
import type { Message, Backlink } from '@anticrm/chunter'
|
import type { Message, Backlink } from '@anticrm/chunter'
|
||||||
import { parse, Node, HTMLElement } from 'node-html-parser'
|
import { parse, Node, HTMLElement } from 'node-html-parser'
|
||||||
@ -48,6 +48,9 @@ function getBacklinks (backlinkId: Ref<Doc>, content: string): Data<Backlink>[]
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export async function OnMessage (tx: Tx, txFactory: TxFactory): Promise<Tx[]> {
|
export async function OnMessage (tx: Tx, txFactory: TxFactory): Promise<Tx[]> {
|
||||||
|
if (tx._class === core.class.TxCollectionCUD) {
|
||||||
|
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
|
||||||
|
}
|
||||||
if (tx._class === core.class.TxCreateDoc) {
|
if (tx._class === core.class.TxCreateDoc) {
|
||||||
const createTx = tx as TxCreateDoc<Message>
|
const createTx = tx as TxCreateDoc<Message>
|
||||||
if (createTx.objectClass === chunter.class.Message) {
|
if (createTx.objectClass === chunter.class.Message) {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite, TxResult, TxAddCollection, AttachedDoc } from '@anticrm/core'
|
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite, TxResult, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
|
||||||
import core, { Hierarchy, DOMAIN_TX, ModelDb, TxFactory } from '@anticrm/core'
|
import core, { Hierarchy, DOMAIN_TX, ModelDb, TxFactory } from '@anticrm/core'
|
||||||
import type { FullTextAdapterFactory, FullTextAdapter } from './types'
|
import type { FullTextAdapterFactory, FullTextAdapter } from './types'
|
||||||
import { FullTextIndex } from './fulltext'
|
import { FullTextIndex } from './fulltext'
|
||||||
@ -107,13 +107,16 @@ class TServerStorage implements ServerStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async processCollection (tx: Tx): Promise<Tx[]> {
|
async processCollection (tx: Tx): Promise<Tx[]> {
|
||||||
if (tx._class === core.class.TxAddCollection) {
|
if (tx._class === core.class.TxCollectionCUD) {
|
||||||
const createTx = tx as TxAddCollection<AttachedDoc>
|
const colTx = tx as TxCollectionCUD<Doc, AttachedDoc>
|
||||||
const _id = createTx.attachedTo
|
const _id = colTx.objectId
|
||||||
const _class = createTx.attachedToClass
|
const _class = colTx.objectClass
|
||||||
const attachedTo = (await this.findAll(_class, { _id }))[0]
|
let attachedTo: Doc | undefined
|
||||||
const txFactory = new TxFactory(tx.modifiedBy)
|
if (colTx.tx._class === core.class.TxCreateDoc) {
|
||||||
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { [createTx.collection]: 1 } })]
|
attachedTo = (await this.findAll(_class, { _id }))[0]
|
||||||
|
const txFactory = new TxFactory(tx.modifiedBy)
|
||||||
|
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { [colTx.collection]: 1 } })]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Tx, Doc, TxCreateDoc, Ref, Account, Hierarchy } from '@anticrm/core'
|
import type { Tx, Doc, TxCreateDoc, Ref, Account, Hierarchy, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
|
||||||
import core, { TxFactory } from '@anticrm/core'
|
import core, { TxFactory } from '@anticrm/core'
|
||||||
|
|
||||||
import { getResource } from '@anticrm/platform'
|
import { getResource } from '@anticrm/platform'
|
||||||
@ -29,6 +29,9 @@ export class Triggers {
|
|||||||
private readonly triggers: TriggerFunc[] = []
|
private readonly triggers: TriggerFunc[] = []
|
||||||
|
|
||||||
async tx (tx: Tx): Promise<void> {
|
async tx (tx: Tx): Promise<void> {
|
||||||
|
if (tx._class === core.class.TxCollectionCUD) {
|
||||||
|
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
|
||||||
|
}
|
||||||
if (tx._class === core.class.TxCreateDoc) {
|
if (tx._class === core.class.TxCreateDoc) {
|
||||||
const createTx = tx as TxCreateDoc<Doc>
|
const createTx = tx as TxCreateDoc<Doc>
|
||||||
if (createTx.objectClass === serverCore.class.Trigger) {
|
if (createTx.objectClass === serverCore.class.Trigger) {
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
"eslint":"^7.32.0"
|
"eslint":"^7.32.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anticrm/core": "~0.6.11",
|
"@anticrm/core": "~0.6.12",
|
||||||
"@anticrm/platform": "~0.6.5",
|
"@anticrm/platform": "~0.6.5",
|
||||||
"@anticrm/server-core": "~0.6.0",
|
"@anticrm/server-core": "~0.6.1",
|
||||||
"@anticrm/view": "~0.6.0"
|
"@anticrm/view": "~0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import type { Tx, TxFactory, Doc, TxCreateDoc, DocWithState, State, TxRemoveDoc } from '@anticrm/core'
|
import type { Tx, TxFactory, Doc, TxCreateDoc, DocWithState, State, TxRemoveDoc, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
|
||||||
import type { FindAll } from '@anticrm/server-core'
|
import type { FindAll } from '@anticrm/server-core'
|
||||||
|
|
||||||
import core, { Hierarchy } from '@anticrm/core'
|
import core, { Hierarchy } from '@anticrm/core'
|
||||||
@ -24,6 +24,10 @@ import view, { Kanban } from '@anticrm/view'
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export async function OnDocWithState (tx: Tx, txFactory: TxFactory, findAll: FindAll<Doc>, hierarchy: Hierarchy): Promise<Tx[]> {
|
export async function OnDocWithState (tx: Tx, txFactory: TxFactory, findAll: FindAll<Doc>, hierarchy: Hierarchy): Promise<Tx[]> {
|
||||||
|
if (tx._class === core.class.TxCollectionCUD) {
|
||||||
|
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
|
||||||
|
}
|
||||||
|
|
||||||
if (hierarchy.isDerived(tx._class, core.class.TxCreateDoc)) {
|
if (hierarchy.isDerived(tx._class, core.class.TxCreateDoc)) {
|
||||||
const createTx = tx as TxCreateDoc<DocWithState>
|
const createTx = tx as TxCreateDoc<DocWithState>
|
||||||
if (hierarchy.isDerived(createTx.objectClass, core.class.DocWithState)) {
|
if (hierarchy.isDerived(createTx.objectClass, core.class.DocWithState)) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user