@sap/xsodata
Version:
Expose data from a HANA database as OData V2 service with help of .xsodata files.
147 lines (132 loc) • 4.46 kB
JavaScript
;
const ModelFileError = require('./errors/modelFileError');
function clone(objectToClone) {
return JSON.parse(JSON.stringify(objectToClone));
}
//API
module.exports = {
getTargetEnd: getTargetEnd,
getFromEnd: getFromEnd,
createFromRoleString: makeStringCreator(getFromEnd),
createToRoleString: makeStringCreator(getTargetEnd),
};
function getTargetEnd(navigation, association, entityType) {
let ret = null;
if (!navigation.from) {
if (association.principal.type === association.dependent.type) {
throw new ModelFileError('No "from" clause given', context);
} else if (association.principal.type === entityType.name) {
ret = clone(association.dependent);
ret.overRefProp = association.over
? association.over.dependent
: null;
return ret;
} else if (association.dependent.type === entityType.name) {
ret = clone(association.principal);
ret.overRefProp = association.over
? association.over.principal
: null;
return ret;
}
} else if (navigation.from.principal === true) {
ret = clone(association.dependent);
ret.overRefProp = association.over ? association.over.dependent : null;
return ret;
} else if (navigation.from.dependent === true) {
ret = clone(association.principal);
ret.overRefProp = association.over ? association.over.principal : null;
return ret;
} else {
throw new ModelFileError('Invalid "from" clause', context);
}
}
function getFromEnd(navigation, association, entityType) {
let ret = null;
if (!navigation.from) {
if (association.principal.type === association.dependent.type) {
throw new ModelFileError('No "from" clause given', context);
} else if (association.principal.type === entityType.name) {
ret = clone(association.principal);
ret.overRefProp = association.over
? association.over.principal
: null;
return ret;
} else if (association.dependent.type === entityType.name) {
ret = clone(association.dependent);
ret.overRefProp = association.over
? association.over.dependent
: null;
return ret;
}
} else if (navigation.from.principal === true) {
ret = clone(association.principal);
ret.overRefProp = association.over ? association.over.principal : null;
return ret;
} else if (navigation.from.dependent === true) {
ret = clone(association.dependent);
ret.overRefProp = association.over ? association.over.dependent : null;
return ret;
} else {
throw new ModelFileError('Invalid "from" clause', context);
}
}
function makeStringCreator(getAssociationEnd) {
return function createAssociationEndString(
navigation,
association,
entityType
) {
const associationEnd = getAssociationEnd(
navigation,
association,
entityType
);
return (
associationEnd.type +
createPrincipalDependantString(associationEnd, association)
);
};
}
function isArrayEqual(a, b) {
if (a === undefined && b === undefined) {
return true;
}
if (a === null && b === null) {
return true;
}
if (!a || !b) {
return false;
}
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function createPrincipalDependantString(associationEnd, association) {
if (
isArrayEqual(
associationEnd.joinproperties,
association.principal.joinproperties
) &&
associationEnd.multiplicity === association.principal.multiplicity &&
associationEnd.type === association.principal.type
) {
return 'Principal';
}
if (
isArrayEqual(
associationEnd.joinproperties,
association.dependent.joinproperties
) &&
associationEnd.multiplicity === association.dependent.multiplicity &&
associationEnd.type === association.dependent.type
) {
return 'Dependent';
}
return '';
}