UNPKG

@cheetah.js/orm

Version:
158 lines (157 loc) 6.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SqlColumnManager = void 0; class SqlColumnManager { constructor(entityStorage, statements, entity) { this.entityStorage = entityStorage; this.statements = statements; this.entity = entity; } generateColumns(model, updatedColumns) { const baseColumns = this.getColumnsForEntity(model, this.statements.alias); const joinColumns = this.getJoinColumns(); const allColumns = [...baseColumns, ...joinColumns]; return [...allColumns, ...updatedColumns]; } processUserColumns(columns) { const aliasedColumns = this.extractAliases(columns); return this.filterValid(aliasedColumns); } getColumnsForEntity(entity, alias) { const entityOptions = this.entityStorage.get(entity); if (!entityOptions) { throw new Error('Entity not found'); } const propertyColumns = this.getPropertyColumns(entityOptions, alias); const relationColumns = this.getRelationColumns(entityOptions, alias); return [...propertyColumns, ...relationColumns]; } discoverAlias(column, onlyAlias = false) { if (!this.isNestedColumn(column)) { return this.buildSimpleColumnAlias(column, this.statements.alias, onlyAlias); } return this.buildNestedColumnAlias(column, onlyAlias); } getJoinColumns() { if (!this.statements.join) { return []; } return this.statements.join.flatMap(join => this.getColumnsForEntity(join.joinEntity, join.joinAlias)); } getPropertyColumns(entityOptions, alias) { return Object.keys(entityOptions.properties).map(key => { const columnName = entityOptions.properties[key].options.columnName; return `${alias}."${columnName}" as "${alias}_${columnName}"`; }); } getRelationColumns(entityOptions, alias) { if (!entityOptions.relations) { return []; } return entityOptions.relations .filter(relation => relation.relation === 'many-to-one') .map(relation => `${alias}."${relation.columnName}" as "${alias}_${relation.columnName}"`); } extractAliases(columns) { return columns .map(column => this.discoverAlias(column)) .flat() .filter((col) => col !== undefined); } filterValid(columns) { return columns.filter(Boolean); } isNestedColumn(column) { return column.includes('.'); } buildSimpleColumnAlias(column, alias, onlyAlias) { const columnName = this.getColumnNameFromProperty(column); if (onlyAlias) { return `${alias}."${columnName}"`; } return `${alias}."${columnName}" as ${alias}_${columnName}`; } buildNestedColumnAlias(column, onlyAlias) { this.validateJoinsExist(); const parts = column.split('.'); const aliasInfo = this.resolveNestedAlias(parts); if (!aliasInfo) { return undefined; } return this.formatColumnWithAlias(aliasInfo.alias, parts[parts.length - 1], onlyAlias); } validateJoinsExist() { if (!this.statements.join && !this.statements.selectJoin) { throw new Error('Join not found'); } } resolveNestedAlias(parts) { const joinMaps = this.buildJoinMaps(); let currentAlias = this.statements.alias; for (let i = 0; i < parts.length; i++) { const part = parts[i]; const isLastPart = i === parts.length - 1; if (isLastPart) { return { alias: currentAlias }; } const nextAlias = this.findNextAlias(part, joinMaps, i === 0); if (!nextAlias) { return null; } currentAlias = nextAlias; } return { alias: currentAlias }; } buildJoinMaps() { const relationsMap = new Map(this.entity.relations.map(rel => [rel.propertyKey, rel])); const joinMap = new Map(); this.statements.join?.forEach(join => joinMap.set(join.joinProperty, join)); const selectJoinMap = new Map(); this.statements.selectJoin?.forEach(join => selectJoinMap.set(join.joinProperty, join)); return { joinMap, selectJoinMap, relationsMap }; } findNextAlias(part, maps, isFirstPart) { if (maps.joinMap.has(part)) { return maps.joinMap.get(part).joinAlias; } if (maps.selectJoinMap.has(part)) { return null; } return null; } formatColumnWithAlias(alias, propertyName, onlyAlias) { const entity = this.getEntityFromAlias(alias); const columnName = this.getColumnNameFromPropertyForEntity(propertyName, entity); if (onlyAlias) { return `${alias}."${columnName}"`; } return `${alias}."${columnName}" as ${alias}_${columnName}`; } getColumnNameFromProperty(propertyName) { return this.getColumnNameFromPropertyForEntity(propertyName, this.entity); } getColumnNameFromPropertyForEntity(propertyName, entity) { if (entity.properties[propertyName]) { return entity.properties[propertyName].options.columnName; } const relation = entity.relations?.find(rel => rel.propertyKey === propertyName); if (relation) { return relation.columnName; } return propertyName; } getEntityFromAlias(alias) { if (alias === this.statements.alias) { return this.entity; } const join = this.statements.join?.find(j => j.joinAlias === alias); if (join?.joinEntity) { const entity = this.entityStorage.get(join.joinEntity); if (entity) { return entity; } } return this.entity; } } exports.SqlColumnManager = SqlColumnManager;