mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 21:50:34 +03:00
UBER-810 Split mixin update to doc and mixin (#3643)
Signed-off-by: Alexander Onnikov <alexander.onnikov@xored.com>
This commit is contained in:
parent
c3197951c8
commit
e80844e18e
@ -219,7 +219,7 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
||||
return this.client.tx(tx)
|
||||
}
|
||||
|
||||
update<T extends Doc>(
|
||||
async update<T extends Doc>(
|
||||
doc: T,
|
||||
update: DocumentUpdate<T>,
|
||||
retrieve?: boolean,
|
||||
@ -229,13 +229,22 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
||||
const hierarchy = this.client.getHierarchy()
|
||||
const mixClass = Hierarchy.mixinOrClass(doc)
|
||||
if (hierarchy.isMixin(mixClass)) {
|
||||
// TODO: Rework it is wrong, we need to split values to mixin update and original document update if mixed.
|
||||
const baseClass = hierarchy.getBaseClass(doc._class)
|
||||
return this.updateMixin(doc._id, baseClass, doc.space, mixClass, update, modifiedOn, modifiedBy)
|
||||
|
||||
const byClass = this.splitMixinUpdate(update, mixClass, baseClass)
|
||||
const ops = this.apply(doc._id)
|
||||
for (const it of byClass) {
|
||||
if (hierarchy.isMixin(it[0])) {
|
||||
await ops.updateMixin(doc._id, baseClass, doc.space, it[0], it[1], modifiedOn, modifiedBy)
|
||||
} else {
|
||||
await ops.updateDoc(it[0], doc.space, doc._id, it[1], retrieve, modifiedOn, modifiedBy)
|
||||
}
|
||||
}
|
||||
return await ops.commit()
|
||||
}
|
||||
if (hierarchy.isDerived(doc._class, core.class.AttachedDoc)) {
|
||||
const adoc = doc as unknown as AttachedDoc
|
||||
return this.updateCollection(
|
||||
return await this.updateCollection(
|
||||
doc._class,
|
||||
doc.space,
|
||||
adoc._id,
|
||||
@ -248,7 +257,7 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
||||
modifiedBy
|
||||
)
|
||||
}
|
||||
return this.updateDoc(doc._class, doc.space, doc._id, update, retrieve, modifiedOn, modifiedBy)
|
||||
return await this.updateDoc(doc._class, doc.space, doc._id, update, retrieve, modifiedOn, modifiedBy)
|
||||
}
|
||||
|
||||
remove<T extends Doc>(doc: T, modifiedOn?: Timestamp, modifiedBy?: Ref<Account>): Promise<TxResult> {
|
||||
@ -322,6 +331,56 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
private splitMixinUpdate<T extends Doc>(
|
||||
update: DocumentUpdate<T>,
|
||||
mixClass: Ref<Class<T>>,
|
||||
baseClass: Ref<Class<T>>
|
||||
): Map<Ref<Class<Doc>>, DocumentUpdate<T>> {
|
||||
const hierarchy = this.getHierarchy()
|
||||
const attributes = hierarchy.getAllAttributes(mixClass)
|
||||
|
||||
const updateAttrs = Object.fromEntries(
|
||||
Object.entries(update).filter((it) => !it[0].startsWith('$'))
|
||||
) as DocumentUpdate<T>
|
||||
const updateOps = Object.fromEntries(
|
||||
Object.entries(update).filter((it) => it[0].startsWith('$'))
|
||||
) as DocumentUpdate<T>
|
||||
|
||||
const result: Map<Ref<Class<Doc>>, DocumentUpdate<T>> = this.splitObjectAttributes(
|
||||
updateAttrs,
|
||||
baseClass,
|
||||
attributes
|
||||
)
|
||||
|
||||
for (const [key, value] of Object.entries(updateOps)) {
|
||||
const updates = this.splitObjectAttributes(value as object, baseClass, attributes)
|
||||
|
||||
for (const [opsClass, opsUpdate] of updates) {
|
||||
const upd: DocumentUpdate<T> = result.get(opsClass) ?? {}
|
||||
result.set(opsClass, { ...upd, [key]: opsUpdate })
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private splitObjectAttributes<T extends object>(
|
||||
obj: T,
|
||||
objClass: Ref<Class<Doc>>,
|
||||
attributes: Map<String, AnyAttribute>
|
||||
): Map<Ref<Class<Doc>>, object> {
|
||||
const hierarchy = this.getHierarchy()
|
||||
|
||||
const result: Map<Ref<Class<Doc>>, any> = new Map()
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const attributeOf = attributes.get(key)?.attributeOf
|
||||
const clazz = attributeOf !== undefined && hierarchy.isMixin(attributeOf) ? attributeOf : objClass
|
||||
result.set(clazz, { ...(result.get(clazz) ?? {}), [key]: value })
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"target": "ES2019",
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"strict": true,
|
||||
|
Loading…
Reference in New Issue
Block a user