mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 18:56:00 +00:00
designer - refactor
This commit is contained in:
131
packages/web/src/designer/designerTools.ts
Normal file
131
packages/web/src/designer/designerTools.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import _ from 'lodash';
|
||||
import { dumpSqlSelect, Select, JoinType, Condition, Relation, mergeConditions, Source } from 'dbgate-sqltree';
|
||||
import { EngineDriver } from 'dbgate-types';
|
||||
import { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
||||
import { DesignerComponentCreator } from './DesignerComponentCreator';
|
||||
import { DesignerQueryDumper } from './DesignerQueryDumper';
|
||||
|
||||
export function referenceIsConnecting(
|
||||
reference: DesignerReferenceInfo,
|
||||
tables1: DesignerTableInfo[],
|
||||
tables2: DesignerTableInfo[]
|
||||
) {
|
||||
return (
|
||||
(tables1.find((x) => x.designerId == reference.sourceId) &&
|
||||
tables2.find((x) => x.designerId == reference.targetId)) ||
|
||||
(tables1.find((x) => x.designerId == reference.targetId) && tables2.find((x) => x.designerId == reference.sourceId))
|
||||
);
|
||||
}
|
||||
|
||||
export function referenceIsJoin(reference) {
|
||||
return ['INNER JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'FULL OUTER JOIN'].includes(reference.joinType);
|
||||
}
|
||||
export function referenceIsExists(reference) {
|
||||
return ['WHERE EXISTS', 'WHERE NOT EXISTS'].includes(reference.joinType);
|
||||
}
|
||||
export function referenceIsCrossJoin(reference) {
|
||||
return !reference.joinType || reference.joinType == 'CROSS JOIN';
|
||||
}
|
||||
|
||||
export function findConnectingReference(
|
||||
designer: DesignerInfo,
|
||||
tables1: DesignerTableInfo[],
|
||||
tables2: DesignerTableInfo[],
|
||||
additionalCondition: (ref: DesignerReferenceInfo) => boolean
|
||||
) {
|
||||
for (const ref of designer.references) {
|
||||
if (additionalCondition(ref) && referenceIsConnecting(ref, tables1, tables2)) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findQuerySource(designer: DesignerInfo, designerId: string): Source {
|
||||
const table = designer.tables.find((x) => x.designerId == designerId);
|
||||
if (!table) return null;
|
||||
return {
|
||||
name: table,
|
||||
alias: table.alias,
|
||||
};
|
||||
}
|
||||
|
||||
export function mergeSelectsFromDesigner(select1: Select, select2: Select): Select {
|
||||
return {
|
||||
commandType: 'select',
|
||||
from: {
|
||||
...select1.from,
|
||||
relations: [
|
||||
...select1.from.relations,
|
||||
{
|
||||
joinType: 'CROSS JOIN',
|
||||
name: select2.from.name,
|
||||
alias: select2.from.alias,
|
||||
},
|
||||
...select2.from.relations,
|
||||
],
|
||||
},
|
||||
where: mergeConditions(select1.where, select2.where),
|
||||
};
|
||||
}
|
||||
|
||||
export function findPrimaryTable(tables: DesignerTableInfo[]) {
|
||||
return _.minBy(tables, (x) => x.top);
|
||||
}
|
||||
|
||||
export function getReferenceConditions(reference: DesignerReferenceInfo, designer: DesignerInfo): Condition[] {
|
||||
const sourceTable = designer.tables.find((x) => x.designerId == reference.sourceId);
|
||||
const targetTable = designer.tables.find((x) => x.designerId == reference.targetId);
|
||||
|
||||
return reference.columns.map((col) => ({
|
||||
conditionType: 'binary',
|
||||
operator: '=',
|
||||
left: {
|
||||
exprType: 'column',
|
||||
columnName: col.source,
|
||||
source: {
|
||||
name: sourceTable,
|
||||
alias: sourceTable.alias,
|
||||
},
|
||||
},
|
||||
right: {
|
||||
exprType: 'column',
|
||||
columnName: col.target,
|
||||
source: {
|
||||
name: targetTable,
|
||||
alias: targetTable.alias,
|
||||
},
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
export function generateDesignedQuery(designer: DesignerInfo, engine: EngineDriver) {
|
||||
const { tables, columns, references } = designer;
|
||||
const primaryTable = findPrimaryTable(designer.tables);
|
||||
if (!primaryTable) return '';
|
||||
const componentCreator = new DesignerComponentCreator(designer);
|
||||
const designerDumper = new DesignerQueryDumper(designer, componentCreator.components);
|
||||
const select = designerDumper.run();
|
||||
|
||||
const dmp = engine.createDumper();
|
||||
dumpSqlSelect(dmp, select);
|
||||
return dmp.s;
|
||||
}
|
||||
|
||||
export function isConnectedByReference(
|
||||
designer: DesignerInfo,
|
||||
table1: { designerId: string },
|
||||
table2: { designerId: string },
|
||||
withoutRef: { designerId: string }
|
||||
) {
|
||||
const creator = new DesignerComponentCreator({
|
||||
...designer,
|
||||
references: withoutRef
|
||||
? designer.references.filter((x) => x.designerId != withoutRef.designerId)
|
||||
: designer.references,
|
||||
});
|
||||
const arrays = creator.components.map((x) => x.thisAndSubComponentsTables);
|
||||
const array1 = arrays.find((a) => a.find((x) => x.designerId == table1.designerId));
|
||||
const array2 = arrays.find((a) => a.find((x) => x.designerId == table2.designerId));
|
||||
return array1 == array2;
|
||||
}
|
||||
Reference in New Issue
Block a user