lambdaorm-base
Version:
304 lines • 12.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DomainConfigServiceBase = void 0;
const domain_1 = require("../../../domain");
class DomainConfigServiceBase {
getEntity(name) {
return this.entities.find(p => p.name === name);
}
getForcedEntity(name) {
const entity = this.getEntity(name);
if (entity === undefined) {
throw new domain_1.SchemaError(`entity ${name} not found`);
}
return entity;
}
getEnum(name) {
return this.enums.find(p => p.name === name);
}
isChild(entityName) {
for (const i in this.entities) {
const entity = this.entities[i];
for (const j in entity.relations) {
const relation = entity.relations[j];
if (relation.type === domain_1.RelationType.manyToOne && relation.composite && relation.entity === entityName)
return true;
}
}
return false;
}
existsProperty(entityName, name) {
var _a;
const entity = this.getEntity(entityName);
if (!entity) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
const property = (_a = entity.properties) === null || _a === void 0 ? void 0 : _a.find(p => p.name === name);
return property !== undefined;
}
getProperty(entityName, name) {
var _a;
const entity = this.getEntity(entityName);
if (!entity) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
const property = (_a = entity.properties) === null || _a === void 0 ? void 0 : _a.find(p => p.name === name);
if (!property) {
throw new domain_1.SchemaError('Not exists property: ' + name + ' in entity: ' + entityName);
}
return property;
}
getAutoIncrement(entityName) {
var _a;
const entity = this.getEntity(entityName);
if (!entity) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
return (_a = entity.properties) === null || _a === void 0 ? void 0 : _a.find(p => p.autoIncrement === true);
}
getFieldIds(entityName) {
var _a;
const entity = this.getEntity(entityName);
if (!entity) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
if (!entity.primaryKey) {
return undefined;
}
return (_a = entity.properties) === null || _a === void 0 ? void 0 : _a.filter(p => entity.primaryKey && entity.primaryKey.includes(p.name));
}
listEntities() {
return this.entities.map(p => p.name);
}
/**
* Sort a list of entities according to their relationships
* @param allEntities entities to order
* @returns returns the sorted entities
*/
sortByRelations(mainEntities, allEntities) {
if (mainEntities.length < 2)
return mainEntities;
const sorted = [];
let tries = 0;
let solved = true;
while (sorted.length < mainEntities.length) {
if (tries >= 1000) {
solved = false;
break;
}
for (const entityName of mainEntities) {
if (sorted.includes(entityName)) {
continue;
}
if (this.solveSortEntity(entityName, mainEntities, allEntities, sorted)) {
sorted.push(entityName);
break;
}
}
tries++;
}
if (solved) {
return sorted;
}
const info = [];
for (const entityName of mainEntities) {
if (!sorted.includes(entityName)) {
const entity = this.getEntity(entityName);
if (entity === undefined) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
info.push(`{ ${entity.name} relations: `);
if (entity.dependents && entity.dependents.length > 0 && entity.relations) {
for (const relation of entity.relations) {
if (relation.entity !== entity.name && mainEntities.includes(relation.entity)) {
for (const relation of entity.relations) {
if (this.unsolvedRelation(entityName, mainEntities, allEntities, sorted, relation)) {
info.push(`${relation.entity}.${relation.name} `);
}
}
}
}
}
info.push('}, ');
}
}
throw new domain_1.SchemaError(`Task cannot be completed because the following entities cannot be sorted by their relations ${info.join('')}`);
}
/**
* Sort a list of entities according to their dependencies
* @param entities entities to order
* @returns returns the sorted entities
*/
sortByDependencies(entities = []) {
if (entities.length < 2)
return entities;
const sorted = [];
let tries = 0;
let solved = true;
while (sorted.length < entities.length) {
if (tries >= 1000) {
solved = false;
break;
}
for (const entityName of entities) {
if (sorted.includes(entityName)) {
continue;
}
const entity = this.getEntity(entityName);
if (entity === undefined) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
if (!this.hadDependencies(entity, entities, sorted)) {
sorted.push(entityName);
break;
}
}
tries++;
}
if (solved) {
return sorted;
}
const info = [];
for (const entityName of entities) {
if (!sorted.includes(entityName)) {
const entity = this.getEntity(entityName);
if (entity === undefined) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
info.push(`{ ${entity.name} depend: `);
if (entity.dependents && entity.dependents.length > 0) {
for (const dependent of entity.dependents) {
if (dependent.entity !== entity.name && entities.includes(dependent.entity)) {
for (const dependent of entity.dependents) {
if (dependent.entity !== entity.name && entities.includes(dependent.entity)) {
if (this.hadDependents(entity, sorted, dependent)) {
info.push(`${dependent.entity}.${dependent.relation.name} `);
}
}
}
}
}
}
info.push('}, ');
}
}
throw new domain_1.SchemaError(`Task cannot be completed because the following entities cannot be sorted by their dependencies ${info.join('')}`);
}
/**
* Determines whether an entity can be included in the entity list based on its relationships
* @param entityName name of entity
* @param sorted current list of entities sorted by dependencies
* @param parent entity parent , used in manyToOne relations
* @returns
*/
solveSortEntity(entityName, mainEntities, allEntities, sorted, parent) {
const entity = this.getEntity(entityName);
if (entity === undefined) {
throw new domain_1.SchemaError('Not exists entity:' + entityName);
}
if (entity.relations === undefined || entity.relations.length === 0) {
return true;
}
else {
let unsolved = false;
for (const relation of entity.relations) {
if (this.unsolvedRelation(entityName, mainEntities, allEntities, sorted, relation, parent)) {
unsolved = true;
break;
}
}
return !unsolved;
}
}
unsolvedRelation(entityName, mainEntities, allEntities, sorted, relation, parent) {
if (relation.entity !== entityName && allEntities.includes(relation.entity)) {
if (relation.type === domain_1.RelationType.oneToOne || relation.type === domain_1.RelationType.oneToMany) {
if (!relation.weak && !sorted.includes(relation.entity) && (parent === null || parent !== relation.entity)) {
return true;
}
}
else if (relation.type === domain_1.RelationType.manyToOne) {
if (relation.composite && !this.solveSortEntity(relation.entity, mainEntities, allEntities, sorted, entityName)) {
return true;
}
}
}
return false;
}
/**
* Determines whether an entity can be included in the entity list based on its dependencies
* @param entityName name of entity
* @param sorted current list of entities sorted by dependencies
* @param parent entity parent , used in manyToOne relations
* @returns
*/
hadDependencies(entity, entities, sorted, parent) {
if (entity.dependents === undefined || entity.dependents.length === 0) {
return false;
}
else {
let hadDependents = false;
for (const dependent of entity.dependents) {
if (dependent.entity !== entity.name && entities.includes(dependent.entity)) {
if (this.hadDependents(entity, sorted, dependent, parent)) {
hadDependents = true;
break;
}
}
}
return hadDependents;
}
}
hadDependents(entity, sorted, dependent, parent) {
var _a;
// if the relationship is not weak
if (!dependent.relation.weak) {
// look for the related property to see if the dependency is not required
const dependentEntity = this.getEntity(dependent.entity);
if (dependentEntity === undefined) {
throw new domain_1.SchemaError('Not exists entity:' + dependent.entity);
}
const dependentProperty = (_a = dependentEntity.properties) === null || _a === void 0 ? void 0 : _a.find(p => p.name === dependent.relation.from);
if (dependentProperty === undefined) {
throw new domain_1.SchemaError(`property ${dependent.relation.from} not found in ${entity.name} `);
}
// if the relation is not required
// and the related entity is not included in the entities sorted by dependency
// and the parent entity is null or is the same as the relation
// in this case it cannot be determined that this entity can still be included in the list of entities ordered by dependency.
if (dependentProperty.required && !sorted.includes(dependent.entity) && (parent === null || parent !== dependent.entity)) {
return true;
}
}
return false;
}
getRelation(entity, relation) {
let _previousEntity, previousEntity, relationData, _relationEntity, relationEntity;
const parts = relation.split('.');
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (i === 0) {
_previousEntity = entity;
previousEntity = this.getEntity(_previousEntity);
}
else {
_previousEntity = _relationEntity;
previousEntity = relationEntity;
}
relationData = previousEntity.relations.find(p => p.name === part);
if (!relationData) {
throw new domain_1.SchemaError('relation ' + part + ' not found in ' + previousEntity.name);
}
_relationEntity = relationData.entity;
relationEntity = this.getEntity(_relationEntity);
}
return {
previousRelation: parts.length > 1 ? parts.slice(0, parts.length - 1).join('.') : '',
previousEntity: previousEntity,
entity: relationEntity,
relation: relationData
};
}
}
exports.DomainConfigServiceBase = DomainConfigServiceBase;
//# sourceMappingURL=domainConfigServiceBase.js.map