sql tree refactor

This commit is contained in:
Jan Prochazka
2020-03-05 12:23:07 +01:00
parent bf607fcb06
commit 95ae39e0de
13 changed files with 291 additions and 123 deletions

View File

@@ -1,5 +1,5 @@
import GridDisplay from "./GridDisplay";
import { Select } from "@dbgate/sqltree";
import { Select, treeToSql, dumpSqlSelect } from "@dbgate/sqltree";
import { TableInfo, EngineDriver } from "@dbgate/types";
import GridConfig from "./GridConfig";
@@ -14,9 +14,11 @@ export default class TableGridDisplay extends GridDisplay {
}
createSelect() {
const select = new Select();
select.from = this.table;
select.selectAll = true;
const select: Select = {
commandType: "select",
from: this.table,
selectAll: true
};
return select;
}
@@ -25,7 +27,7 @@ export default class TableGridDisplay extends GridDisplay {
if (this.driver.dialect.limitSelect) select.topRecords = count;
if (this.driver.dialect.rangeSelect)
select.range = { offset: offset, limit: count };
const sql = select.toSql(this.driver);
const sql = treeToSql(this.driver, select, dumpSqlSelect);
return sql;
}
}

View File

@@ -1,11 +1,14 @@
import { EngineDriver, SqlDumper } from "@dbgate/types";
import { NamedObjectInfo, RangeDefinition } from "@dbgate/types";
export class Command {
toSql(driver: EngineDriver) {
const dumper = driver.createDumper();
this.dumpSql(dumper);
return dumper.s;
}
dumpSql(dumper: SqlDumper) {}
}
// import { EngineDriver, SqlDumper } from "@dbgate/types";
// export class Command {
// toSql(driver: EngineDriver) {
// const dumper = driver.createDumper();
// this.dumpSql(dumper);
// return dumper.s;
// }
// dumpSql(dumper: SqlDumper) {}
// }

View File

@@ -1,9 +1,9 @@
import { SqlDumper } from "@dbgate/types";
// import { SqlDumper } from "@dbgate/types";
export abstract class Condition {
abstract dumpSql(dumper: SqlDumper) ;
}
// export abstract class Condition {
// abstract dumpSql(dumper: SqlDumper) ;
// }
export abstract class UnaryCondition extends Condition {
// expr: Expresssion;
}
// export abstract class UnaryCondition extends Condition {
// // expr: Expresssion;
// }

View File

@@ -1,4 +1,4 @@
export abstract class Expression {
// export abstract class Expression {
}
// }

View File

@@ -1,29 +1,29 @@
import { Command } from "./Command";
import { NamedObjectInfo, RangeDefinition, SqlDumper } from "@dbgate/types";
// import { Command } from "./Command";
// import { NamedObjectInfo, RangeDefinition, SqlDumper } from "@dbgate/types";
export class Select extends Command {
topRecords: number;
from: NamedObjectInfo;
range: RangeDefinition;
distinct = false;
selectAll = false;
// export class Select extends Command {
// topRecords: number;
// from: NamedObjectInfo;
// range: RangeDefinition;
// distinct = false;
// selectAll = false;
dumpSql(dumper: SqlDumper) {
dumper.put("^select ");
if (this.topRecords) {
dumper.put("^top %s ", this.topRecords);
}
if (this.distinct) {
dumper.put("^distinct ");
}
if (this.selectAll) {
dumper.put("* ");
} else {
// TODO
}
dumper.put("^from %f ", this.from);
if (this.range) {
dumper.put("^limit %s ^offset %s ", this.range.limit, this.range.offset);
}
}
}
// dumpSql(dumper: SqlDumper) {
// dumper.put("^select ");
// if (this.topRecords) {
// dumper.put("^top %s ", this.topRecords);
// }
// if (this.distinct) {
// dumper.put("^distinct ");
// }
// if (this.selectAll) {
// dumper.put("* ");
// } else {
// // TODO
// }
// dumper.put("^from %f ", this.from);
// if (this.range) {
// dumper.put("^limit %s ^offset %s ", this.range.limit, this.range.offset);
// }
// }
// }

View File

@@ -1,78 +1,78 @@
import { SqlDumper, NamedObjectInfo } from "@dbgate/types";
import { Select } from "./Select";
// import { SqlDumper, NamedObjectInfo } from "@dbgate/types";
// import { Select } from "./Select";
export class Source {
name: NamedObjectInfo;
alias: string;
subQuery: Select;
subQueryString: string;
// export class Source {
// name: NamedObjectInfo;
// alias: string;
// subQuery: Select;
// subQueryString: string;
dumpSqlDef(dumper: SqlDumper) {
let sources = 0;
if (this.name != null) sources++;
if (this.subQuery != null) sources++;
if (this.subQueryString != null) sources++;
if (sources != 1)
throw new Error("sqltree.Source should have exactly one source");
// dumpSqlDef(dumper: SqlDumper) {
// let sources = 0;
// if (this.name != null) sources++;
// if (this.subQuery != null) sources++;
// if (this.subQueryString != null) sources++;
// if (sources != 1)
// throw new Error("sqltree.Source should have exactly one source");
if (this.name != null) {
dumper.put("%f", this.name);
}
if (this.subQuery) {
dumper.put("(");
this.subQuery.dumpSql(dumper);
dumper.put(")");
}
if (this.subQueryString) {
dumper.put("(");
dumper.putRaw(this.subQueryString);
dumper.put(")");
}
if (this.alias) {
dumper.put(" %i", this.alias);
}
}
// if (this.name != null) {
// dumper.put("%f", this.name);
// }
// if (this.subQuery) {
// dumper.put("(");
// this.subQuery.dumpSql(dumper);
// dumper.put(")");
// }
// if (this.subQueryString) {
// dumper.put("(");
// dumper.putRaw(this.subQueryString);
// dumper.put(")");
// }
// if (this.alias) {
// dumper.put(" %i", this.alias);
// }
// }
dumpSqlRef(dumper: SqlDumper) {
if (this.alias != null) {
dumper.put("%i", this.alias);
return true;
} else if (this.name != null) {
dumper.put("%f", this.name);
return true;
}
return false;
}
}
// dumpSqlRef(dumper: SqlDumper) {
// if (this.alias != null) {
// dumper.put("%i", this.alias);
// return true;
// } else if (this.name != null) {
// dumper.put("%f", this.name);
// return true;
// }
// return false;
// }
// }
class Relation {
source:Source;
joinType: string;
// conditions:
// class Relation {
// source:Source;
// joinType: string;
// // conditions:
// dumpSqlRef(dumper: SqlDumper) {
// // dumpSqlRef(dumper: SqlDumper) {
// dumper.put("&n");
// dumper.putRaw(this.joinType);
// dumper.put(" ");
// this.source.dumpSqlDef(dumper)
// if (Conditions.Any())
// {
// dumper.put(" ^on ");
// bool was = false;
// foreach (var cond in Conditions)
// {
// if (was) dumper.put(" ^and ");
// cond.GenSql(dmp);
// was = true;
// }
// }
// }
// // dumper.put("&n");
// // dumper.putRaw(this.joinType);
// // dumper.put(" ");
// // this.source.dumpSqlDef(dumper)
// // if (Conditions.Any())
// // {
// // dumper.put(" ^on ");
// // bool was = false;
// // foreach (var cond in Conditions)
// // {
// // if (was) dumper.put(" ^and ");
// // cond.GenSql(dmp);
// // was = true;
// // }
// // }
// // }
}
// }
export class FromDefinition {
source: Source;
relations: Relation[] = [];
}
// export class FromDefinition {
// source: Source;
// relations: Relation[] = [];
// }

View File

@@ -0,0 +1,29 @@
import { SqlDumper } from "@dbgate/types";
import { Command, Select } from "./types";
export function dumpSqlSelect(dmp: SqlDumper, select: Select) {
dmp.put("^select ");
if (select.topRecords) {
dmp.put("^top %s ", select.topRecords);
}
if (select.distinct) {
dmp.put("^distinct ");
}
if (select.selectAll) {
dmp.put("* ");
} else {
// TODO
}
dmp.put("^from %f ", select.from);
if (select.range) {
dmp.put("^limit %s ^offset %s ", select.range.limit, select.range.offset);
}
}
export function dumpSqlCommand(dmp: SqlDumper, command: Command) {
switch (command.commandType) {
case "select":
dumpSqlSelect(dmp, command as Select);
break;
}
}

View File

@@ -0,0 +1,20 @@
import { SqlDumper } from "@dbgate/types";
import { Expression, ColumnRefExpression } from "./types";
import { dumpSqlSourceRef } from "./dumpSqlSource";
function dumpSqlColumnRef(dumper: SqlDumper, expr: ColumnRefExpression) {
if (expr.source) {
if (dumpSqlSourceRef(dumper, expr.source)) {
dumper.put(".");
}
}
dumper.put("%i", expr.columnName);
}
export function dumpSqlExpression(dumper: SqlDumper, expr: Expression) {
switch (expr.exprType) {
case "column":
dumpSqlColumnRef(dumper, expr as ColumnRefExpression);
break;
}
}

View File

@@ -0,0 +1,40 @@
import { Source } from "./types";
import { SqlDumper } from "@dbgate/types";
import { dumpSqlSelect } from "./dumpSqlCommand";
export function dumpSqlSourceDef(dmp: SqlDumper, source: Source) {
let sources = 0;
if (source.name != null) sources++;
if (source.subQuery != null) sources++;
if (source.subQueryString != null) sources++;
if (sources != 1)
throw new Error("sqltree.Source should have exactly one source");
if (source.name != null) {
dmp.put("%f", source.name);
}
if (source.subQuery) {
dmp.put("(");
dumpSqlSelect(dmp, source.subQuery);
dmp.put(")");
}
if (source.subQueryString) {
dmp.put("(");
dmp.putRaw(source.subQueryString);
dmp.put(")");
}
if (source.alias) {
dmp.put(" %i", this.alias);
}
}
export function dumpSqlSourceRef(dmp: SqlDumper, source: Source) {
if (source.alias) {
dmp.put("%i", source.alias);
return true;
} else if (source.name) {
dmp.put("%f", source.name);
return true;
}
return false;
}

View File

@@ -1,2 +1,3 @@
export { Select } from "./Select";
export { Command } from "./Command";
export * from "./types";
export * from "./dumpSqlCommand";
export * from "./treeToSql";

View File

@@ -0,0 +1,11 @@
import { EngineDriver, SqlDumper } from "@dbgate/types";
export function treeToSql<T>(
driver: EngineDriver,
object: T,
func: (dmp: SqlDumper, obj: T) => void
) {
const dmp = driver.createDumper();
func(dmp, object);
return dmp.s;
}

View File

@@ -0,0 +1,62 @@
import { NamedObjectInfo, RangeDefinition } from "@dbgate/types";
export interface Command {
commandType: "select";
}
export interface Select extends Command {
from: NamedObjectInfo;
topRecords?: number;
range?: RangeDefinition;
distinct?: boolean;
selectAll?: boolean;
}
export interface Condition {
conditionType: "eq" | "not";
}
export interface UnaryCondition extends Condition {
expr: Expression;
}
export interface BinaryCondition extends Condition {
left: Expression;
right: Expression;
}
export interface NotCondition extends UnaryCondition {
conditionType: "not";
}
export interface Source {
name: NamedObjectInfo;
alias: string;
subQuery: Select;
subQueryString: string;
}
export type JoinType = "LEFT JOIN" | "INNER JOIN" | "RIGHT JOIN";
export interface Relation {
source: Source;
conditions: Condition[];
joinType: JoinType;
}
export interface Expression {
exprType: "column" | "value" | "string" | "literal" | "count";
}
export interface ColumnRefExpression extends Expression {
exprType: "column";
columnName: string;
source: Source;
}
export interface ValueExpression extends Expression {
exprType: "value";
value: any;
}

View File

@@ -11,8 +11,8 @@ export default function TableCreateScriptTab({ conid, database, schemaName, pure
// console.log(tableInfo);
const driver = engines(connnection.engine);
const dumper = driver.createDumper();
if (tableInfo) dumper.createTable(tableInfo);
const dmp = driver.createDumper();
if (tableInfo) dmp.createTable(tableInfo);
return <SqlEditor engine={connnection && connnection.engine} value={dumper.s} />;
return <SqlEditor engine={connnection && connnection.engine} value={dmp.s} />;
}