in source/packages/services/assetlibrary/src/groups/groups.full.dao.ts [227:292]
public async update(n: Node, groups?: DirectionToRelatedEntityArrayMap): Promise<string> {
logger.debug(`groups.full.dao update: in: n:${JSON.stringify(n)}`);
const id = `group___${n.attributes['groupPath'].toString()}`;
const conn = await super.getConnection();
const traversal = conn.traversal.V(id).as('group');
// drop() step terminates a traversal, process all drops as part of a final union step
const dropTraversals: process.GraphTraversal[] = [];
for (const [key, val] of Object.entries(n.attributes)) {
if (val !== undefined) {
if (val === null) {
dropTraversals.push(__.properties(key));
} else {
traversal.property(process.cardinality.single, key, val);
}
}
}
// Check if related groups part of update request
if (groups?.in || groups?.out) {
// Update request contains relationships to enforce. This requires current
// relationships be dropped where specified and new relations created.
logger.info(
`groups.full.dao update groups relations specified as part of update: ${JSON.stringify(
{ groups: groups }
)}`
);
const result = await this.get([`${n.attributes['groupPath']}`], true);
let currentGroup: GroupItem;
if (result !== undefined && result.length > 0) {
currentGroup = this.groupsAssembler.toGroupItem(result[0]);
}
const existingGroups = currentGroup.groups ? currentGroup.groups : {};
logger.debug(`Current group definition: ${JSON.stringify(currentGroup)}`);
// Methodology
// 1. Collect relations to be dropped as independent traversal objects via disassociateRels
// 2. Union and then drop() these with traversal.sideEffect(...)
// -- Use of sideEffect acts on the traversal then passes results to next step. Without this, a drop() will terminate traversal.
// 3. Add specified relations for groups and devices directly to traversal in associateRels
const relationsToDropTraversals: process.GraphTraversal[] = [];
if (groups.in && 'in' in existingGroups) {
disassociateRels(relationsToDropTraversals, existingGroups.in, 'in');
}
if (groups.out && 'out' in existingGroups) {
disassociateRels(relationsToDropTraversals, existingGroups.out, 'out');
}
traversal.sideEffect(__.union(...relationsToDropTraversals).drop());
if (groups.in) {
associateRels(traversal, groups.in, 'in');
}
if (groups.out) {
associateRels(traversal, groups.out, 'out');
}
}
if (dropTraversals.length > 0) {
traversal.local(__.union(...dropTraversals)).drop();
}
await traversal.iterate();
logger.debug(`groups.full.dao update: exit: id:${id}`);
return id;
}