public async update()

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:`);
    }