Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 1x 1x 1x 1x 1x 35x 35x 1x 34x 3x 1x 34x 2x 34x 3x 34x 4x 34x 9x 12x 9x 9x 4x 9x 2x 1x 7x 1x 2x 1x 2x 2x 34x 4x 1x 3x 3x 1x 1x | "use strict";
const _ = require("lodash");
const AnnotationTarget = require("../annotations/AnnotationTarget");
const CollectionType = require("./CollectionType");
const OnDeleteAction = require("./OnDeleteAction");
const ReferentialConstraint = require("./ReferentialConstraint");
/**
* Envelops a navigation property.
*
* http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_NavigationProperty
*
*
* @class NavigationProperty
* @extends {AnnotationTarget}
*/
class NavigationProperty extends AnnotationTarget {
/**
* Creates an instance of NavigationProperty.
* @param {Object} rawMetadata raw metadata object for NavigationProperty
* @memberof NavigationProperty
*/
constructor(rawMetadata) {
super(rawMetadata);
if (!this.name) {
throw new Error("Name attribute is mandatory for NavigationProperty.");
}
if (_.has(this.raw.$, "Partner")) {
// there is quite a lot of logic related to Partner attribute
// see http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_PartnerNavigationProperty
// since it is not used in library so far, only value is stored if specified, and no check are performed
Object.defineProperty(this, "partner", {
get: () => this.raw.$.Partner,
});
}
// there is quite a lot of logic related to ContainsTarget attribute
// see http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_ContainmentNavigationProperty
// since it is not used in library so far, only value is stored, and no check are performed
Object.defineProperty(this, "containsTarget", {
get: () => this.raw.$.ContainsTarget === "true",
});
let constraints = (rawMetadata.ReferentialConstraint || []).map(
(c) => new ReferentialConstraint(c)
);
Object.defineProperty(this, "referentialConstraints", {
get: () => constraints,
});
this._processOnDelete(rawMetadata);
}
/**
* Initializes schema dependent properties. Decoupled from constructor,
* because it needs to resolve schema (type) references.
*
* @param {CsdlSchema} schema to resolve references
* @memberof NavigationProperty
*/
initSchemaDependentProperties(schema) {
Object.defineProperty(this, "type", {
get: () => schema.getType(this.raw.$.Type),
});
let isCollection = this.type instanceof CollectionType;
Object.defineProperty(this, "isCollection", {
get: () => isCollection,
});
if (isCollection) {
if (_.has(this.raw.$, "Nullable")) {
throw new Error(
"Nullable MUST NOT be specified for a collection-valued navigation property."
);
}
} else {
Object.defineProperty(this, "nullable", {
get: () => this.raw.$.Nullable !== "false",
});
}
}
/**
* Gets navigation property target information.
*
* @param {CsdlSchema} schema to resolve model paths
* @param {EntitySet|Singleton} source model of the source set/singleton
* @returns {Object} navigation property target
* @memberof NavigationProperty
*/
getTarget(schema, source) {
let navigationBinding = source.navigationPropertyBindings.filter(
(b) => b.path === this.name
)[0];
// Target must resolve to an entity set, singleton, or direct or indirect containment navigation property of a singleton in scope.
// The path can traverse single-valued containment navigation properties or single-valued complex properties before ending in a containment
// navigation property, and there MUST NOT be any non-containment navigation properties prior to the final segment.
// we are currently assuming that the target can be entity set only
let entitySet = navigationBinding
? schema.getEntityContainer().resolveModelPath(navigationBinding.target)
: undefined;
return {
entitySet: entitySet,
entityType: this.type,
isMultiple: this.isCollection,
};
}
_processOnDelete(rawMetadata) {
if (_.has(rawMetadata, "OnDelete")) {
if (rawMetadata.OnDelete.length > 1) {
throw new Error(
"NavigationProperty may contain at most one child element OnDelete."
);
}
let onDelete = new OnDeleteAction(rawMetadata.OnDelete[0]);
Object.defineProperty(this, "onDelete", {
get: () => onDelete,
});
}
}
}
module.exports = NavigationProperty;
|