diff --git a/packages/datalib/src/TableGridDisplay.ts b/packages/datalib/src/TableGridDisplay.ts index 5a45c11e0..c2e99b003 100644 --- a/packages/datalib/src/TableGridDisplay.ts +++ b/packages/datalib/src/TableGridDisplay.ts @@ -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; } } diff --git a/packages/sqltree/src/Command.ts b/packages/sqltree/src/Command.ts index a95a2d6e7..4eed61808 100644 --- a/packages/sqltree/src/Command.ts +++ b/packages/sqltree/src/Command.ts @@ -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) {} +// } diff --git a/packages/sqltree/src/Condition.ts b/packages/sqltree/src/Condition.ts index 6bdbb4440..f58bbe90b 100644 --- a/packages/sqltree/src/Condition.ts +++ b/packages/sqltree/src/Condition.ts @@ -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; -} \ No newline at end of file +// export abstract class UnaryCondition extends Condition { +// // expr: Expresssion; +// } \ No newline at end of file diff --git a/packages/sqltree/src/Expression.ts b/packages/sqltree/src/Expression.ts index ea31b98ee..f38af7601 100644 --- a/packages/sqltree/src/Expression.ts +++ b/packages/sqltree/src/Expression.ts @@ -1,4 +1,4 @@ -export abstract class Expression { +// export abstract class Expression { -} +// } diff --git a/packages/sqltree/src/Select.ts b/packages/sqltree/src/Select.ts index 7426043c2..67eafe6ee 100644 --- a/packages/sqltree/src/Select.ts +++ b/packages/sqltree/src/Select.ts @@ -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); +// } +// } +// } diff --git a/packages/sqltree/src/Source.ts b/packages/sqltree/src/Source.ts index d3ba051b8..4389f28f6 100644 --- a/packages/sqltree/src/Source.ts +++ b/packages/sqltree/src/Source.ts @@ -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[] = []; +// } diff --git a/packages/sqltree/src/dumpSqlCommand.ts b/packages/sqltree/src/dumpSqlCommand.ts new file mode 100644 index 000000000..0a2f232d4 --- /dev/null +++ b/packages/sqltree/src/dumpSqlCommand.ts @@ -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; + } +} diff --git a/packages/sqltree/src/dumpSqlExpression.ts b/packages/sqltree/src/dumpSqlExpression.ts new file mode 100644 index 000000000..00e7a3582 --- /dev/null +++ b/packages/sqltree/src/dumpSqlExpression.ts @@ -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; + } +} diff --git a/packages/sqltree/src/dumpSqlSource.ts b/packages/sqltree/src/dumpSqlSource.ts new file mode 100644 index 000000000..7a133c765 --- /dev/null +++ b/packages/sqltree/src/dumpSqlSource.ts @@ -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; +} diff --git a/packages/sqltree/src/index.ts b/packages/sqltree/src/index.ts index a5afece79..9d0a99ad7 100644 --- a/packages/sqltree/src/index.ts +++ b/packages/sqltree/src/index.ts @@ -1,2 +1,3 @@ -export { Select } from "./Select"; -export { Command } from "./Command"; +export * from "./types"; +export * from "./dumpSqlCommand"; +export * from "./treeToSql"; diff --git a/packages/sqltree/src/treeToSql.ts b/packages/sqltree/src/treeToSql.ts new file mode 100644 index 000000000..63264050d --- /dev/null +++ b/packages/sqltree/src/treeToSql.ts @@ -0,0 +1,11 @@ +import { EngineDriver, SqlDumper } from "@dbgate/types"; + +export function treeToSql( + driver: EngineDriver, + object: T, + func: (dmp: SqlDumper, obj: T) => void +) { + const dmp = driver.createDumper(); + func(dmp, object); + return dmp.s; +} diff --git a/packages/sqltree/src/types.ts b/packages/sqltree/src/types.ts new file mode 100644 index 000000000..82451787f --- /dev/null +++ b/packages/sqltree/src/types.ts @@ -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; +} + diff --git a/packages/web/src/tabs/TableCreateScriptTab.js b/packages/web/src/tabs/TableCreateScriptTab.js index 2217c31f9..8a6b173fc 100644 --- a/packages/web/src/tabs/TableCreateScriptTab.js +++ b/packages/web/src/tabs/TableCreateScriptTab.js @@ -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 ; + return ; }