Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2023-06-01 00:17:45 +06:00 committed by GitHub
parent 565b823847
commit 79121cb8b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 98 deletions

View File

@ -17,7 +17,7 @@ import activity from '@hcengineering/activity'
import chunter from '@hcengineering/chunter'
import type { EmployeeAccount } from '@hcengineering/contact'
import contact from '@hcengineering/contact'
import { Doc, Domain, IndexKind, Ref, TxCUD } from '@hcengineering/core'
import { Domain, IndexKind, Ref, Tx } from '@hcengineering/core'
import {
ArrOf,
Builder,
@ -33,12 +33,12 @@ import {
} from '@hcengineering/model'
import { TComment } from '@hcengineering/model-chunter'
import core, { TAttachedDoc, TClass } from '@hcengineering/model-core'
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
import view from '@hcengineering/model-view'
import notification from '@hcengineering/notification'
import { Request, RequestDecisionComment, RequestPresenter, RequestStatus } from '@hcengineering/request'
import { AnyComponent } from '@hcengineering/ui'
import request from './plugin'
import notification from '@hcengineering/notification'
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
export { requestId } from '@hcengineering/request'
export { default } from './plugin'
@ -62,7 +62,7 @@ export class TRequest extends TAttachedDoc implements Request {
@Index(IndexKind.Indexed)
status!: RequestStatus
tx!: TxCUD<Doc>
tx!: Tx
@Prop(TypeRef(contact.class.EmployeeAccount), request.string.Rejected)
@ReadOnly()

View File

@ -13,12 +13,12 @@
// limitations under the License.
//
import { Comment } from '@hcengineering/chunter'
import { EmployeeAccount } from '@hcengineering/contact'
import type { AttachedDoc, Class, Doc, Mixin, Ref, TxCUD } from '@hcengineering/core'
import type { AttachedDoc, Class, Doc, Mixin, Ref, Tx } from '@hcengineering/core'
import type { Asset, IntlString, Plugin } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { AnyComponent } from '@hcengineering/ui'
import { Comment } from '@hcengineering/chunter'
/**
* @public
@ -29,7 +29,7 @@ export interface Request extends AttachedDoc {
requiredApprovesCount: number
rejected?: Ref<EmployeeAccount>
status: RequestStatus
tx: TxCUD<Doc>
tx: Tx
comments?: number
}

View File

@ -606,110 +606,99 @@ class TServerStorage implements ServerStorage {
return { passed, onEnd }
}
async apply (ctx: MeasureContext, tx: Tx[], broadcast: boolean): Promise<Tx[]> {
const triggerFx = new Effects()
const _findAll = createFindAll(this)
async apply (ctx: MeasureContext, txes: Tx[], broadcast: boolean): Promise<Tx[]> {
const result = await this.processTxes(ctx, txes)
let derived: Tx[] = []
const txToStore = tx.filter(
(it) => it.space !== core.space.DerivedTx && !this.hierarchy.isDerived(it._class, core.class.TxApplyIf)
)
await ctx.with('domain-tx', {}, async () => await this.getAdapter(DOMAIN_TX).tx(...txToStore))
derived = result[1]
const removedMap = new Map<Ref<Doc>, Doc>()
await ctx.with('apply', {}, (ctx) => this.routeTx(ctx, removedMap, ...tx))
// send transactions
if (broadcast) {
this.options?.broadcast?.(tx)
}
// invoke triggers and store derived objects
const derived = await this.processDerived(ctx, tx, triggerFx, _findAll, removedMap)
// index object
for (const _tx of tx) {
await ctx.with('fulltext', {}, (ctx) => this.fulltext.tx(ctx, _tx))
}
// index derived objects
for (const tx of derived) {
await ctx.with('derived-processor', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
}
for (const fx of triggerFx.effects) {
await fx()
}
if (broadcast && derived.length > 0) {
this.options?.broadcast?.(txes)
this.options?.broadcast?.(derived)
}
return [...tx, ...derived]
return [...txes, ...derived]
}
async tx (ctx: MeasureContext, tx: Tx): Promise<[TxResult, Tx[]]> {
// store tx
const _class = txClass(tx)
const _findAll = createFindAll(this)
const objClass = txObjectClass(tx)
const removedDocs = new Map<Ref<Doc>, Doc>()
return await ctx.with('tx', { _class, objClass }, async (ctx) => {
if (tx.space !== core.space.DerivedTx && !this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
await ctx.with('domain-tx', { _class, objClass }, async () => await this.getAdapter(DOMAIN_TX).tx(tx))
fillTxes (txes: Tx[], txToStore: Tx[], modelTx: Tx[], txToProcess: Tx[], applyTxes: Tx[]): void {
for (const tx of txes) {
if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
if (tx.space !== core.space.DerivedTx) {
txToStore.push(tx)
}
if (tx.objectSpace === core.space.Model) {
modelTx.push(tx)
}
txToProcess.push(tx)
} else {
applyTxes.push(tx)
}
}
}
if (tx.objectSpace === core.space.Model) {
async processTxes (ctx: MeasureContext, txes: Tx[]): Promise<[TxResult, Tx[]]> {
// store tx
const _findAll = createFindAll(this)
const txToStore: Tx[] = []
const modelTx: Tx[] = []
const applyTxes: Tx[] = []
const txToProcess: Tx[] = []
const triggerFx = new Effects()
const removedMap = new Map<Ref<Doc>, Doc>()
const onEnds: (() => void)[] = []
let result: TxResult = {}
let derived: Tx[] = []
try {
this.fillTxes(txes, txToStore, modelTx, txToProcess, applyTxes)
for (const tx of applyTxes) {
const applyIf = tx as TxApplyIf
// Wait for scope promise if found
const passed = await this.verifyApplyIf(ctx, applyIf, _findAll)
onEnds.push(passed.onEnd)
if (passed.passed) {
this.fillTxes(applyIf.txes, txToStore, modelTx, txToProcess, applyTxes)
derived = [...applyIf.txes]
}
}
for (const tx of modelTx) {
// maintain hierarchy and triggers
this.hierarchy.tx(tx)
await this.triggers.tx(tx)
await this.modelDb.tx(tx)
this.model.push(tx)
}
await ctx.with('domain-tx', {}, async () => await this.getAdapter(DOMAIN_TX).tx(...txToStore))
result = await ctx.with('apply', {}, (ctx) => this.routeTx(ctx, removedMap, ...txToProcess))
const triggerFx = new Effects()
// invoke triggers and store derived objects
derived = derived.concat(await this.processDerived(ctx, txToProcess, triggerFx, _findAll, removedMap))
let result: TxResult = {}
let derived: Tx[] = []
let onEnd = (): void => {}
try {
if (this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
const applyIf = tx as TxApplyIf
// Wait for scope promise if found
let passed: boolean
;({ passed, onEnd } = await this.verifyApplyIf(ctx, applyIf, _findAll))
result = passed
if (passed) {
// Store apply if transaction's if required
await ctx.with('domain-tx', { _class, objClass }, async () => {
const atx = await this.getAdapter(DOMAIN_TX)
await atx.tx(...applyIf.txes)
})
derived = await this.processDerivedTxes(applyIf.txes, ctx, triggerFx, _findAll, removedDocs)
}
} else {
// store object
result = await ctx.with('route-tx', { _class, objClass }, (ctx) => this.routeTx(ctx, removedDocs, tx))
// invoke triggers and store derived objects
derived = await this.processDerived(ctx, [tx], triggerFx, _findAll, removedDocs)
}
// index object
await ctx.with('fulltext', { _class, objClass }, (ctx) => this.fulltext.tx(ctx, tx))
// index derived objects
for (const tx of derived) {
await ctx.with('derived-fulltext', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
}
for (const fx of triggerFx.effects) {
await fx()
}
} catch (err: any) {
console.log(err)
throw err
} finally {
onEnd()
// index object
for (const _tx of txToProcess) {
await ctx.with('fulltext', {}, (ctx) => this.fulltext.tx(ctx, _tx))
}
return [result, derived]
})
// index derived objects
for (const tx of derived) {
await ctx.with('derived-processor', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
}
for (const fx of triggerFx.effects) {
await fx()
}
} catch (err: any) {
console.log(err)
throw err
} finally {
onEnds.forEach((p) => p())
}
return [result, derived]
}
async tx (ctx: MeasureContext, tx: Tx): Promise<[TxResult, Tx[]]> {
return await this.processTxes(ctx, [tx])
}
find (domain: Domain): StorageIterator {
@ -742,12 +731,6 @@ class Effects {
}
}
function txObjectClass (tx: Tx): string {
return tx._class === core.class.TxCollectionCUD
? (tx as TxCollectionCUD<Doc, AttachedDoc>).tx.objectClass
: (tx as TxCUD<Doc>).objectClass
}
function txClass (tx: Tx): Ref<Class<Tx>> {
return tx._class === core.class.TxCollectionCUD ? (tx as TxCollectionCUD<Doc, AttachedDoc>).tx._class : tx._class
}