@cheetah.js/orm
Version:
A simple ORM for Cheetah.js
129 lines (128 loc) • 4.86 kB
JavaScript
"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) {
if (onlyAlias) {
return `${alias}."${column}"`;
}
return `${alias}."${column}" as ${alias}_${column}`;
}
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, columnName, onlyAlias) {
if (onlyAlias) {
return `${alias}."${columnName}"`;
}
return `${alias}."${columnName}" as ${alias}_${columnName}`;
}
}
exports.SqlColumnManager = SqlColumnManager;