UNPKG

lambdaorm-base

Version:
304 lines 12.9 kB
"use strict"; 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