in source/packages/services/assetlibrary/src/devices/devices.full.dao.ts [354:480]
public async update(
n: Node,
groups?: DirectionToRelatedEntityArrayMap,
devices?: DirectionToRelatedEntityArrayMap
): Promise<void> {
logger.debug(`devices.full.dao update: in: n:${JSON.stringify(n)}`);
const id = `device___${n.attributes['deviceId']}`;
const conn = await super.getConnection();
const traversal = conn.traversal.V(id).as('device');
// 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 or devices part of update request
if (groups !== undefined && (groups.in || groups.out || devices.in || devices.out)) {
// Update request contains relationships to enforce. This requires current
// relationships be dropped where specified and new relations created.
logger.info(
`devices.full.dao update groups/devices relations specified as part of update: ${JSON.stringify(
{ groups: groups }
)}/${JSON.stringify({ devices: devices })}`
);
const result = await this.get([`${n.attributes['deviceId']}`], false, [], false);
let currentDevice: DeviceItem;
if (result !== undefined && result.length > 0) {
currentDevice = this.devicesAssembler.toDeviceItem(result[0]);
}
const existingGroups = currentDevice.groups ? currentDevice.groups : {};
const existingDevices = currentDevice.devices ? currentDevice.devices : {};
logger.debug(`Current device defintion: ${JSON.stringify(currentDevice)}`);
// Methodology
// 1. Collect relations to be dropped as independent traversal objects via diassociateRels
// 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) {
logger.debug(
`devices.full.dao update device ${id} dropping existing relations for groups.in: ${JSON.stringify(
existingGroups.in
)}`
);
diassociateRels(relationsToDropTraversals, existingGroups.in, 'group', 'in');
}
if (groups.out && 'out' in existingGroups) {
logger.debug(
`devices.full.dao update device ${id} dropping existing relations for groups.out: ${JSON.stringify(
existingGroups.out
)}`
);
diassociateRels(relationsToDropTraversals, existingGroups.out, 'group', 'out');
}
if (devices.in && 'in' in existingDevices) {
logger.debug(
`devices.full.dao update device ${id} dropping existing relations for devices.in: ${JSON.stringify(
existingDevices.in
)}`
);
diassociateRels(relationsToDropTraversals, existingDevices.in, 'device', 'in');
}
if (devices.out && 'out' in existingDevices) {
logger.debug(
`devices.full.dao update device ${id} dropping existing relations for devices.out:: ${JSON.stringify(
existingDevices.out
)}`
);
diassociateRels(
relationsToDropTraversals,
existingDevices.out,
'device',
'out'
);
}
traversal.sideEffect(__.union(...relationsToDropTraversals).drop());
if (groups.in) {
logger.debug(
`devices.full.dao update device ${id} adding relations for groups.in: ${JSON.stringify(
groups.in
)}`
);
associateRels(traversal, groups.in, 'group', 'in');
}
if (groups.out) {
logger.debug(
`devices.full.dao update device ${id} adding relations for groups.out: ${JSON.stringify(
groups.out
)}`
);
associateRels(traversal, groups.out, 'group', 'out');
}
if (devices.in) {
logger.debug(
`devices.full.dao update device ${id} adding relations for devices.in: ${JSON.stringify(
devices.in
)}`
);
associateRels(traversal, devices.in, 'device', 'in');
}
if (devices.out) {
logger.debug(
`devices.full.dao update device ${id} adding relations for devices.out: ${JSON.stringify(
devices.out
)}`
);
associateRels(traversal, devices.out, 'device', 'out');
}
}
if (dropTraversals.length > 0) {
traversal.local(__.union(...dropTraversals)).drop();
}
logger.debug(
`devices.full.dao update traversal before iterate is: ${JSON.stringify(traversal)}`
);
await traversal.iterate();
logger.debug(`devices.full.dao update: exit:`);
}