Skip to content

Commit

Permalink
a40_entityMetadata.js/a44_predicate.js Allow property paths with subt…
Browse files Browse the repository at this point in the history
…ype update

OData 3 supports filtering on subtypes by using syntax such as follows:
Order/Northwind.Models.InternationalOrder/ExciseTax

This change allows for this type of filtering

Updated this change to merge correctly with the latest upstream version
of the repository as of now (3/9/2018). Added a getSubtype method to
EntityType.
  • Loading branch information
tschettler committed Nov 14, 2020
1 parent adc3375 commit 0d830e8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
49 changes: 47 additions & 2 deletions src/a40_entityMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,9 @@ var EntityType = (function () {
var orderDetailType = em1.metadataStore.getEntityType("OrderDetail");
var companyNameProp2 = orderDetailType.getProperty("Order.Customer.CompanyName");
// companyNameProp === companyNameProp2
This method can also walk a property path to return a property in a subtype
@example
var exciseTaxProp = orderDetailType.getProperty("Order/InternationalOrder.ExciseTax");
@method getProperty
@param propertyPath {String}
@param [throwIfNotFound=false] {Boolean} Whether to throw an exception if not found.
Expand All @@ -1797,9 +1800,23 @@ var EntityType = (function () {
var parentType = this;
var key = useServerName ? "nameOnServer" : "name";
var props = propertyNames.map(function (propName) {
// split for casting entity property to subtype
var nameParts = propName.split("/");
propName = nameParts[0];
var subtype = nameParts[1];

var prop = __arrayFirst(parentType.getProperties(), __propEq(key, propName));
if (prop) {
parentType = prop.isNavigationProperty ? prop.entityType : prop.dataType;

// if subtype is specified, use that next
if (subtype) {
// change parentType to subtype
parentType = parentType.getSubtype(subtype, throwIfNotFound);
if (!parentType) {
ok = false;
}
}
} else if (throwIfNotFound) {
throw new Error("unable to locate property: " + propName + " on entityType: " + parentType.name);
} else {
Expand All @@ -1819,8 +1836,20 @@ var EntityType = (function () {
return fn(propName);
});
} else {
propNames = this.getPropertiesOnPath(propertyPath, false, true).map(function(prop) {
return prop.nameOnServer;
var parentType = this;
propNames = this.getPropertiesOnPath(propertyPath, false, true).map(function(prop, index, arr) {
parentType = prop.isNavigationProperty ? prop.entityType : prop.dataType;
var propName = prop.nameOnServer;

// try getting the next property's parent
var nextParentType = (arr[index + 1] || { parentType: parentType }).parentType;

if (nextParentType !== parentType) {
// we can assume this to be a subtype, use the next property's parent
propName = __formatString("%1/%2.%3", propName, nextParentType.namespace, nextParentType.shortName);
}

return propName;
});
}
return propNames.join(delimiter);
Expand All @@ -1834,6 +1863,22 @@ var EntityType = (function () {
return new EntityKey(this, keyValues);
};

/**
Returns the subtype of this type by short name down thru the hierarchy.
@method getSubtype
@param shortName [String]
@param [throwIfNotFound=false] {Boolean} Whether to throw an exception if not found.
**/
proto.getSubtype = function(shortName, throwIfNotFound) {
throwIfNotFound = throwIfNotFound || false;
var subtype = __arrayFirst(this.getSelfAndSubtypes(), __propEq("shortName", shortName));
if (!subtype && throwIfNotFound) {
throw new Error(__formatString("The entityType '%1' is not a subtype of entityType '%2'", shortName, this.name));
}
return subtype;
};

proto._updateTargetFromRaw = function (target, raw, rawValueFn) {
// called recursively for complex properties
this.dataProperties.forEach(function (dp) {
Expand Down
2 changes: 1 addition & 1 deletion src/a44_predicate.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@
return ctor;
})();

var RX_IDENTIFIER = /^[a-z_][\w.$]*$/i;
var RX_IDENTIFIER = /^[a-z_](?:\/?[\w.$])*$/i;
// comma delimited expressions ignoring commas inside of both single and double quotes.
var RX_COMMA_DELIM1 = /('[^']*'|[^,]+)/g;
var RX_COMMA_DELIM2 = /("[^"]*"|[^,]+)/g;
Expand Down

0 comments on commit 0d830e8

Please sign in to comment.