mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
referenco conditions
This commit is contained in:
parent
5558869ff4
commit
10a213d8a3
@ -1,5 +1,5 @@
|
|||||||
import { EngineDriver, SqlDumper } from 'dbgate-types';
|
import { EngineDriver, SqlDumper } from 'dbgate-types';
|
||||||
import { Command } from './types';
|
import { Command, Condition } from './types';
|
||||||
import { dumpSqlCommand } from './dumpSqlCommand';
|
import { dumpSqlCommand } from './dumpSqlCommand';
|
||||||
|
|
||||||
export function treeToSql<T>(driver: EngineDriver, object: T, func: (dmp: SqlDumper, obj: T) => void) {
|
export function treeToSql<T>(driver: EngineDriver, object: T, func: (dmp: SqlDumper, obj: T) => void) {
|
||||||
@ -16,3 +16,30 @@ export function scriptToSql(driver: EngineDriver, script: Command[]): string {
|
|||||||
}
|
}
|
||||||
return dmp.s;
|
return dmp.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mergeConditions(condition1: Condition, condition2: Condition): Condition {
|
||||||
|
if (!condition1) return condition2;
|
||||||
|
if (!condition2) return condition1;
|
||||||
|
if (condition1.conditionType == 'and' && condition2.conditionType == 'and') {
|
||||||
|
return {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: [...condition1.conditions, ...condition2.conditions],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (condition1.conditionType == 'and') {
|
||||||
|
return {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: [...condition1.conditions, condition2],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (condition2.conditionType == 'and') {
|
||||||
|
return {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: [condition1, ...condition2.conditions],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: [condition1, condition2],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { dumpSqlSelect, Select, JoinType, Condition, Relation } from 'dbgate-sqltree';
|
import { dumpSqlSelect, Select, JoinType, Condition, Relation, mergeConditions } from 'dbgate-sqltree';
|
||||||
import { EngineDriver } from 'dbgate-types';
|
import { EngineDriver } from 'dbgate-types';
|
||||||
import { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
import { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
||||||
|
|
||||||
@ -20,6 +20,12 @@ class DesignerComponent {
|
|||||||
get nonPrimaryTablesAndReferences() {
|
get nonPrimaryTablesAndReferences() {
|
||||||
return _.zip(this.nonPrimaryTables, this.nonPrimaryReferences);
|
return _.zip(this.nonPrimaryTables, this.nonPrimaryReferences);
|
||||||
}
|
}
|
||||||
|
get myAndParentTables() {
|
||||||
|
return [...this.parentTables, ...this.tables];
|
||||||
|
}
|
||||||
|
get parentTables() {
|
||||||
|
return this.parentComponent ? this.parentComponent.myAndParentTables : [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function referenceIsConnecting(
|
function referenceIsConnecting(
|
||||||
@ -40,6 +46,9 @@ function referenceIsJoin(reference) {
|
|||||||
function referenceIsExists(reference) {
|
function referenceIsExists(reference) {
|
||||||
return ['WHERE EXISTS', 'WHERE NOT EXISTS'].includes(reference.joinType);
|
return ['WHERE EXISTS', 'WHERE NOT EXISTS'].includes(reference.joinType);
|
||||||
}
|
}
|
||||||
|
function referenceIsCrossJoin(reference) {
|
||||||
|
return !reference.joinType || reference.joinType == 'CROSS JOIN';
|
||||||
|
}
|
||||||
|
|
||||||
function findConnectingReference(
|
function findConnectingReference(
|
||||||
designer: DesignerInfo,
|
designer: DesignerInfo,
|
||||||
@ -113,21 +122,6 @@ class DesignerComponentCreator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeConditions(condition1: Condition, condition2: Condition): Condition {
|
|
||||||
if (!condition1) return condition2;
|
|
||||||
if (!condition2) return condition1;
|
|
||||||
if (condition1.conditionType == 'and' && condition2.conditionType == 'and') {
|
|
||||||
return {
|
|
||||||
conditionType: 'and',
|
|
||||||
conditions: [...condition1.conditions, ...condition2.conditions],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
conditionType: 'and',
|
|
||||||
conditions: [condition1, condition2],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeSelects(select1: Select, select2: Select): Select {
|
function mergeSelects(select1: Select, select2: Select): Select {
|
||||||
return {
|
return {
|
||||||
commandType: 'select',
|
commandType: 'select',
|
||||||
@ -147,9 +141,12 @@ function mergeSelects(select1: Select, select2: Select): Select {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
class DesignerQueryDumper {
|
class DesignerQueryDumper {
|
||||||
// dumpedTables: DesignerTableInfo[];
|
|
||||||
constructor(public designer: DesignerInfo, public components: DesignerComponent[]) {}
|
constructor(public designer: DesignerInfo, public components: DesignerComponent[]) {}
|
||||||
|
|
||||||
|
get topLevelTables(): DesignerTableInfo[] {
|
||||||
|
return _.flatten(this.components.map((x) => x.tables));
|
||||||
|
}
|
||||||
|
|
||||||
dumpComponent(component: DesignerComponent) {
|
dumpComponent(component: DesignerComponent) {
|
||||||
const select: Select = {
|
const select: Select = {
|
||||||
commandType: 'select',
|
commandType: 'select',
|
||||||
@ -168,6 +165,33 @@ class DesignerQueryDumper {
|
|||||||
conditions: getReferenceConditions(ref, this.designer),
|
conditions: getReferenceConditions(ref, this.designer),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const subComponent of component.subComponents) {
|
||||||
|
const subQuery = this.dumpComponent(subComponent);
|
||||||
|
subQuery.selectAll = true;
|
||||||
|
select.where = mergeConditions(select.where, {
|
||||||
|
conditionType: subComponent.parentReference.joinType == 'WHERE NOT EXISTS' ? 'notExists' : 'exists',
|
||||||
|
subQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.parentReference) {
|
||||||
|
select.where = mergeConditions(select.where, {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: getReferenceConditions(component.parentReference, this.designer),
|
||||||
|
});
|
||||||
|
|
||||||
|
// cross join conditions in subcomponents
|
||||||
|
for (const ref of this.designer.references) {
|
||||||
|
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, component.tables, component.myAndParentTables)) {
|
||||||
|
select.where = mergeConditions(select.where, {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: getReferenceConditions(ref, this.designer),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return select;
|
return select;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +202,17 @@ class DesignerQueryDumper {
|
|||||||
if (res == null) res = select;
|
if (res == null) res = select;
|
||||||
else res = mergeSelects(res, select);
|
else res = mergeSelects(res, select);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// top level cross join conditions
|
||||||
|
const topLevelTables = this.topLevelTables;
|
||||||
|
for (const ref of this.designer.references) {
|
||||||
|
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, topLevelTables, topLevelTables)) {
|
||||||
|
res.where = mergeConditions(res.where, {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: getReferenceConditions(ref, this.designer),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user