public async update()

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;
    }