<commit_before>const _ = require('lodash');
// const debug = require('debug')('W2:models:relationship');
const Promise = require('bluebird');
const RoutesInfo = require('@quoin/expressjs-routes-info');
const uuid = require('uuid/v4');
const warpjsUtils = require('@warp-works/warpjs-utils');

const Base = require('./base');
const ComplexTypes = require('./../complex-types');
const EntityTypes = require('./../entity-types');
const isLastDocLevel = require('./../is-last-doc-level');
const SpecialRelationships = require('./../special-relationships');
const updatePathInfo = require('./../update-path-info');

const TYPE = ComplexTypes.Relationship;

class Relationship extends Base {
    constructor(parent, target, id, isAggregation, name) {
        super(TYPE, parent, id, name, "");
        this.isAggregation = isAggregation;
        this.targetEntity = [target];
        this.sourceRole = "Source Role";
        this.sourceMin = "1";
        this.sourceMax = "*";
        this.sourceAverage = "/";
        this.targetRole = "Target Role";
        this.targetMin = "0";
        this.targetMax = "*";
        this.targetAverage = "/";

        this.updateDesc();
    }

    // eslint-disable-next-line camelcase
    getParent_Entity() {
        return this.parent;
    }

    updateDesc() {
        var target = this.hasTargetEntity() && typeof this.getTargetEntity() === "object"
            ? this.targetEntity[0].name
            : "undefined";
        if (this.isAggregation) {
            this.desc = `${this.name}: ${this.parent.name}[${target}] (1:${this.getTargetCardinality()})`;
        } else {
            this.desc = `${this.name}: ${this.parent.name}=>${target} (${this.getSourceCardinality()}:${this.getTargetCardinality()})`;
        }
    }

    getTargetReferences(instance) {
        const targetEntity = this.getTargetEntity();
        // debug(`getTargetReferences(): this=`, this.type);
        // debug(`getTargetReferences(): targetEntity=`, targetEntity.type);

        initializeRelationships(instance);

        // debug(`getTargetReferences(): targetEntity=`, targetEntity);
        if (targetEntity.isDocument()) {
            const relationshipReferences = (this.isAggregation) ? instance.aggregations : instance.associations;

            const filtered = relationshipReferences.find((obj) => obj.relnID === this.id);

            if (filtered) {
                return filtered.data;
            } else {
                // The relationship is missing. Add a new one.
                const newRef = {
                    relnID: this.id,
                    relnName: this.name,
                    data: []
                };
                relationshipReferences.push(newRef);
                return newRef.data;
            }
        } else {
            const embedded = instance.embedded.find((embed) => embed.parentRelnID === this.id);
            if (embedded) {
                if (!embedded.entities) {
                    embedded.entities = [];
                }
                return embedded.entities;
            } else {
                // The relationship is missing. Add it.
                const newEmbedded = {
                    parentRelnID: this.id,
                    parentRelnName: this.name,
                    entities: []
                };

                instance.embedded.push(newEmbedded);
                return newEmbedded.entities;
            }
        }
    }

    hasTargetEntity() {
        return this.targetEntity &&
            this.targetEntity.length &&
            this.targetEntity[0] != null &&
            typeof this.targetEntity[0] === "object" &&
            this.targetEntity[0].constructor !== Array;
    }

    getTargetEntity() {
        return this.targetEntity[0];
    }

    setTargetEntity(te) {
        this.targetEntity = te ? [te] : [];
    }

    getTargetCardinality() {
        if (this.targetAverage === "1") {
            return "1";
        } else {
            return parseInt(this.targetAverage) < parseInt(this.getDomain().definitionOfMany) ? "Few" : "Many";
        }
    }

    getSourceCardinality() {
        if (this.sourceAverage === "1") {
            return "1";
        } else {
            return parseInt(this.sourceAverage) < parseInt(this.getDomain().definitionOfMany) ? "Few" : "Many";
        }
    }

    getDocuments(persistence, instance) {
        const targetEntity = this.getTargetEntity();
        const references = this.getTargetReferences(instance);

        if (this.isAggregation) {
            if (!targetEntity.isDocument()) {
                return Promise.resolve(references);
            }

            return targetEntity.getChildren(persistence, instance.id);
        }

        if (targetEntity.isAbstract) {
            const domain = targetEntity.getDomain();
            return Promise.map(references, (reference) => Promise.resolve()
                .then(() => domain.getEntityByName(reference.type))
                .then((nonAbstractEntity) => nonAbstractEntity.getInstance(persistence, reference._id))
                .then((targetInstance) => {
                    targetInstance.relnDesc = reference.desc;
                    return targetInstance;
                })
            );
        }

        return Promise.reduce(
            references,
            (memo, reference) => targetEntity.getInstance(persistence, reference._id)
                .then((targetInstance) => {
                    targetInstance.relnDesc = reference.desc;
                    return targetInstance;
                })
                .then((targetInstance) => memo.concat(targetInstance)),
            []
        );
    }

    toJSON() {
        return _.extend({}, super.toJSON(), {
            isAggregation: this.isAggregation,
            targetEntity: this.hasTargetEntity() ? [this.getTargetEntity().idToJSON()] : [],
            sourceRole: this.sourceRole,
            sourceMin: this.sourceMin,
            sourceMax: this.sourceMax,
            sourceAverage: this.sourceAverage,
            targetRole: this.targetRole,
            targetMin: this.targetMin,
            targetMax: this.targetMax,
            targetAverage: this.targetAverage
        });
    }

    fromJSON(jsonData) {
        super.fromJSON(jsonData);

        this.sourceRole = jsonData.sourceRole;
        this.sourceMin = jsonData.sourceMin;<commit_msg>- Don't return deleted references<commit_after>const _ = require('lodash');
const debug = require('debug')('W2:models:relationship');
const Promise = require('bluebird');
const RoutesInfo = require('@quoin/expressjs-routes-info');
const uuid = require('uuid/v4');
const warpjsUtils = require('@warp-works/warpjs-utils');

const Base = require('./base');
const ComplexTypes = require('./../complex-types');
const EntityTypes = require('./../entity-types');
const isLastDocLevel = require('./../is-last-doc-level');
const SpecialRelationships = require('./../special-relationships');
const updatePathInfo = require('./../update-path-info');

const TYPE = ComplexTypes.Relationship;

class Relationship extends Base {
    constructor(parent, target, id, isAggregation, name) {
        super(TYPE, parent, id, name, "");
        this.isAggregation = isAggregation;
        this.targetEntity = [target];
        this.sourceRole = "Source Role";
        this.sourceMin = "1";
        this.sourceMax = "*";
        this.sourceAverage = "/";
        this.targetRole = "Target Role";
        this.targetMin = "0";
        this.targetMax = "*";
        this.targetAverage = "/";

        this.updateDesc();
    }

    // eslint-disable-next-line camelcase
    getParent_Entity() {
        return this.parent;
    }

    updateDesc() {
        var target = this.hasTargetEntity() && typeof this.getTargetEntity() === "object"
            ? this.targetEntity[0].name
            : "undefined";
        if (this.isAggregation) {
            this.desc = `${this.name}: ${this.parent.name}[${target}] (1:${this.getTargetCardinality()})`;
        } else {
            this.desc = `${this.name}: ${this.parent.name}=>${target} (${this.getSourceCardinality()}:${this.getTargetCardinality()})`;
        }
    }

    getTargetReferences(instance) {
        const targetEntity = this.getTargetEntity();
        // debug(`getTargetReferences(): this=`, this.type);
        // debug(`getTargetReferences(): targetEntity=`, targetEntity.type);

        initializeRelationships(instance);

        // debug(`getTargetReferences(): targetEntity=`, targetEntity);
        if (targetEntity.isDocument()) {
            const relationshipReferences = (this.isAggregation) ? instance.aggregations : instance.associations;

            const filtered = relationshipReferences.find((obj) => obj.relnID === this.id);

            if (filtered) {
                return filtered.data;
            } else {
                // The relationship is missing. Add a new one.
                const newRef = {
                    relnID: this.id,
                    relnName: this.name,
                    data: []
                };
                relationshipReferences.push(newRef);
                return newRef.data;
            }
        } else {
            const embedded = instance.embedded.find((embed) => embed.parentRelnID === this.id);
            if (embedded) {
                if (!embedded.entities) {
                    embedded.entities = [];
                }
                return embedded.entities;
            } else {
                // The relationship is missing. Add it.
                const newEmbedded = {
                    parentRelnID: this.id,
                    parentRelnName: this.name,
                    entities: []
                };

                instance.embedded.push(newEmbedded);
                return newEmbedded.entities;
            }
        }
    }

    hasTargetEntity() {
        return this.targetEntity &&
            this.targetEntity.length &&
            this.targetEntity[0] != null &&
            typeof this.targetEntity[0] === "object" &&
            this.targetEntity[0].constructor !== Array;
    }

    getTargetEntity() {
        return this.targetEntity[0];
    }

    setTargetEntity(te) {
        this.targetEntity = te ? [te] : [];
    }

    getTargetCardinality() {
        if (this.targetAverage === "1") {
            return "1";
        } else {
            return parseInt(this.targetAverage) < parseInt(this.getDomain().definitionOfMany) ? "Few" : "Many";
        }
    }

    getSourceCardinality() {
        if (this.sourceAverage === "1") {
            return "1";
        } else {
            return parseInt(this.sourceAverage) < parseInt(this.getDomain().definitionOfMany) ? "Few" : "Many";
        }
    }

    getDocuments(persistence, instance) {
        const targetEntity = this.getTargetEntity();
        const references = this.getTargetReferences(instance);

        if (this.isAggregation) {
            if (!targetEntity.isDocument()) {
                return Promise.resolve(references);
            }

            return targetEntity.getChildren(persistence, instance.id);
        }

        if (targetEntity.isAbstract) {
            const domain = targetEntity.getDomain();
            return Promise.map(references, (reference) => Promise.resolve()
                .then(() => domain.getEntityByName(reference.type))
                .then((nonAbstractEntity) => nonAbstractEntity.getInstance(persistence, reference._id))
                .then((targetInstance) => {
                    targetInstance.relnDesc = reference.desc;
                    return targetInstance;
                })
            );
        }

        return Promise.resolve()
            .then(() => Promise.reduce(
                references,
                (memo, reference) => targetEntity.getInstance(persistence, reference._id)
                    .then((targetInstance) => {
                        targetInstance.relnDesc = reference.desc;
                        return targetInstance;
                    })
                    .then((targetInstance) => memo.concat(targetInstance)),
                []
            ))
            .then((documents) => documents.filter((doc) => doc.type))
        ;
    }

    toJSON() {
        return _.extend({}, super.toJSON(), {
            isAggregation: this.isAggregation,
            targetEntity: this.hasTargetEntity() ? [this.getTargetEntity().idToJSON()] : [],
            sourceRole: this.sourceRole,
            sourceMin: this.sourceMin,
            sourceMax: this.sourceMax,
            sourceAverage: this.sourceAverage,
            targetRole: this.targetRole,
            targetMin: this.targetMin,
            targetMax: this.targetMax,
            targetAverage: this.targetAverage
        });
    }

    fromJSON(jsonData) {
        super.fromJSON(jsonData);

        this.sourceRole = jsonData.sourceRole;
        this.sourceMin = jsonData.sourceMin;
{'fraction_non_alphanumeric': 0.1297827935379145, 'fraction_numerical': 0.002164334853520909, 'mean_word_length': 1.8924659065504137, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3844221', 'n_tokens_mistral': 3450, 'n_tokens_neox': 3298, 'n_words': 602}