mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-31 20:57:31 +00: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)
|
return this.client.tx(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
update<T extends Doc>(
|
async update<T extends Doc>(
|
||||||
doc: T,
|
doc: T,
|
||||||
update: DocumentUpdate<T>,
|
update: DocumentUpdate<T>,
|
||||||
retrieve?: boolean,
|
retrieve?: boolean,
|
||||||
@ -229,13 +229,22 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
|||||||
const hierarchy = this.client.getHierarchy()
|
const hierarchy = this.client.getHierarchy()
|
||||||
const mixClass = Hierarchy.mixinOrClass(doc)
|
const mixClass = Hierarchy.mixinOrClass(doc)
|
||||||
if (hierarchy.isMixin(mixClass)) {
|
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)
|
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)) {
|
if (hierarchy.isDerived(doc._class, core.class.AttachedDoc)) {
|
||||||
const adoc = doc as unknown as AttachedDoc
|
const adoc = doc as unknown as AttachedDoc
|
||||||
return this.updateCollection(
|
return await this.updateCollection(
|
||||||
doc._class,
|
doc._class,
|
||||||
doc.space,
|
doc.space,
|
||||||
adoc._id,
|
adoc._id,
|
||||||
@ -248,7 +257,7 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
|||||||
modifiedBy
|
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> {
|
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
|
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": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "ES2019",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user