2020-12-29 13:33:03 +00:00
|
|
|
import _ from 'lodash';
|
2022-11-03 15:40:54 +00:00
|
|
|
import type { Select, Condition, Source } from 'dbgate-sqltree';
|
|
|
|
import { dumpSqlSelect, mergeConditions } from 'dbgate-sqltree';
|
|
|
|
import type { EngineDriver } from 'dbgate-types';
|
|
|
|
import type { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
2020-12-29 13:33:03 +00:00
|
|
|
import { DesignerComponentCreator } from './DesignerComponentCreator';
|
|
|
|
import { DesignerQueryDumper } from './DesignerQueryDumper';
|
2020-12-29 16:55:07 +00:00
|
|
|
import { getFilterType } from 'dbgate-filterparser';
|
2020-12-29 13:33:03 +00:00
|
|
|
|
|
|
|
export function referenceIsConnecting(
|
|
|
|
reference: DesignerReferenceInfo,
|
|
|
|
tables1: DesignerTableInfo[],
|
|
|
|
tables2: DesignerTableInfo[]
|
|
|
|
) {
|
|
|
|
return (
|
2021-01-23 06:22:09 +00:00
|
|
|
(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))
|
2020-12-29 13:33:03 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
) {
|
2020-12-30 07:33:39 +00:00
|
|
|
for (const ref of designer.references || []) {
|
2020-12-29 13:33:03 +00:00
|
|
|
if (additionalCondition(ref) && referenceIsConnecting(ref, tables1, tables2)) {
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function findQuerySource(designer: DesignerInfo, designerId: string): Source {
|
2021-01-23 06:22:09 +00:00
|
|
|
const table = designer.tables.find(x => x.designerId == designerId);
|
2020-12-29 13:33:03 +00:00
|
|
|
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[]) {
|
2021-01-23 06:22:09 +00:00
|
|
|
return _.minBy(tables, x => x.top);
|
2020-12-29 13:33:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function getReferenceConditions(reference: DesignerReferenceInfo, designer: DesignerInfo): Condition[] {
|
2021-01-23 06:22:09 +00:00
|
|
|
const sourceTable = designer.tables.find(x => x.designerId == reference.sourceId);
|
|
|
|
const targetTable = designer.tables.find(x => x.designerId == reference.targetId);
|
2020-12-29 13:33:03 +00:00
|
|
|
|
2021-01-23 06:22:09 +00:00
|
|
|
return reference.columns.map(col => ({
|
2020-12-29 13:33:03 +00:00
|
|
|
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();
|
2022-01-02 09:02:31 +00:00
|
|
|
select.distinct = !!designer?.settings?.isDistinct;
|
2020-12-29 13:33:03 +00:00
|
|
|
|
|
|
|
const dmp = engine.createDumper();
|
|
|
|
dumpSqlSelect(dmp, select);
|
|
|
|
return dmp.s;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isConnectedByReference(
|
|
|
|
designer: DesignerInfo,
|
|
|
|
table1: { designerId: string },
|
|
|
|
table2: { designerId: string },
|
|
|
|
withoutRef: { designerId: string }
|
|
|
|
) {
|
2020-12-30 07:33:39 +00:00
|
|
|
if (!designer.references) return false;
|
2020-12-29 13:33:03 +00:00
|
|
|
const creator = new DesignerComponentCreator({
|
|
|
|
...designer,
|
|
|
|
references: withoutRef
|
2021-01-23 06:22:09 +00:00
|
|
|
? designer.references.filter(x => x.designerId != withoutRef.designerId)
|
2020-12-29 13:33:03 +00:00
|
|
|
: designer.references,
|
|
|
|
});
|
2021-01-23 06:22:09 +00:00
|
|
|
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));
|
2020-12-29 13:33:03 +00:00
|
|
|
return array1 == array2;
|
|
|
|
}
|
2020-12-29 16:55:07 +00:00
|
|
|
|
|
|
|
export function findDesignerFilterType({ designerId, columnName }, designer) {
|
2021-01-23 06:22:09 +00:00
|
|
|
const table = (designer.tables || []).find(x => x.designerId == designerId);
|
2020-12-29 16:55:07 +00:00
|
|
|
if (table) {
|
2021-01-23 06:22:09 +00:00
|
|
|
const column = (table.columns || []).find(x => x.columnName == columnName);
|
2020-12-29 16:55:07 +00:00
|
|
|
if (column) {
|
|
|
|
const { dataType } = column;
|
|
|
|
return getFilterType(dataType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 'string';
|
|
|
|
}
|