incremental data loading, flattened some sqltree types

This commit is contained in:
Jan Prochazka 2020-03-05 15:04:06 +01:00
parent 6b3e4e7cbf
commit d4b359f5a0
9 changed files with 45 additions and 33 deletions

View File

@ -1,5 +1,5 @@
import GridDisplay from './GridDisplay'; import GridDisplay from './GridDisplay';
import { Select, treeToSql, dumpSqlSelect, createColumnResultField } from '@dbgate/sqltree'; import { Select, treeToSql, dumpSqlSelect } from '@dbgate/sqltree';
import { TableInfo, EngineDriver } from '@dbgate/types'; import { TableInfo, EngineDriver } from '@dbgate/types';
import GridConfig from './GridConfig'; import GridConfig from './GridConfig';
@ -15,20 +15,26 @@ export default class TableGridDisplay extends GridDisplay {
} }
createSelect() { createSelect() {
const orderColumnName = this.table.columns[0].columnName;
const select: Select = { const select: Select = {
commandType: 'select', commandType: 'select',
from: { from: { name: this.table },
source: { name: this.table }, columns: this.table.columns.map(col => ({ exprType: 'column', ...col })),
orderBy: [
{
exprType: 'column',
columnName: orderColumnName,
direction: 'ASC',
}, },
columns: this.table.columns.map(col => createColumnResultField(col.columnName)), ],
}; };
return select; return select;
} }
getPageQuery(offset: number, count: number) { getPageQuery(offset: number, count: number) {
const select = this.createSelect(); const select = this.createSelect();
if (this.driver.dialect.limitSelect) select.topRecords = count;
if (this.driver.dialect.rangeSelect) select.range = { offset: offset, limit: count }; if (this.driver.dialect.rangeSelect) select.range = { offset: offset, limit: count };
else if (this.driver.dialect.limitSelect) select.topRecords = count;
const sql = treeToSql(this.driver, select, dumpSqlSelect); const sql = treeToSql(this.driver, select, dumpSqlSelect);
return sql; return sql;
} }

View File

@ -5,6 +5,8 @@ const MsSqlDumper = require("./MsSqlDumper");
/** @type {import('@dbgate/types').SqlDialect} */ /** @type {import('@dbgate/types').SqlDialect} */
const dialect = { const dialect = {
limitSelect: true, limitSelect: true,
rangeSelect: true,
offsetFetchRangeSyntax: true,
quoteIdentifier(s) { quoteIdentifier(s) {
return `[${s}]`; return `[${s}]`;
} }

View File

@ -1,10 +0,0 @@
import { ResultField } from './types';
export function createColumnResultField(columnName: string): ResultField {
return {
expr: {
exprType: 'column',
columnName,
},
};
}

View File

@ -18,17 +18,34 @@ export function dumpSqlSelect(dmp: SqlDumper, select: Select) {
if (select.selectAll) dmp.put('&n,'); if (select.selectAll) dmp.put('&n,');
dmp.put('&>&n'); dmp.put('&>&n');
dmp.putCollection(',&n', select.columns, fld => { dmp.putCollection(',&n', select.columns, fld => {
dumpSqlExpression(dmp, fld.expr); dumpSqlExpression(dmp, fld);
if (fld.alias) dmp.put(' %i', fld.alias); if (fld.alias) dmp.put(' %i', fld.alias);
}); });
dmp.put('&n&<'); dmp.put('&n&<');
} }
dmp.put('^from '); dmp.put('^from ');
dumpSqlFromDefinition(dmp, select.from); dumpSqlFromDefinition(dmp, select.from);
if (select.groupBy) {
dmp.put('&ngroup ^by ');
dmp.putCollection(', ', select.groupBy, expr => dumpSqlExpression(dmp, expr));
dmp.put('&n');
}
if (select.orderBy) {
dmp.put('&n^order ^by ');
dmp.putCollection(', ', select.orderBy, expr => {
dumpSqlExpression(dmp, expr);
dmp.put(' %k', expr.direction);
});
dmp.put('&n');
}
if (select.range) { if (select.range) {
if (dmp.dialect.offsetFetchRangeSyntax) {
dmp.put('^offset %s ^rows ^fetch ^next %s ^rows ^only', select.range.offset, select.range.limit);
} else {
dmp.put('^limit %s ^offset %s ', select.range.limit, select.range.offset); dmp.put('^limit %s ^offset %s ', select.range.limit, select.range.offset);
} }
} }
}
export function dumpSqlCommand(dmp: SqlDumper, command: Command) { export function dumpSqlCommand(dmp: SqlDumper, command: Command) {
switch (command.commandType) { switch (command.commandType) {

View File

@ -41,7 +41,7 @@ export function dumpSqlSourceRef(dmp: SqlDumper, source: Source) {
export function dumpSqlRelation(dmp: SqlDumper, from: Relation) { export function dumpSqlRelation(dmp: SqlDumper, from: Relation) {
dmp.put('&n %k ', from.joinType); dmp.put('&n %k ', from.joinType);
dumpSqlSourceDef(dmp, from.source); dumpSqlSourceDef(dmp, from);
if (from.conditions) { if (from.conditions) {
dmp.put(' ^on '); dmp.put(' ^on ');
dmp.putCollection(' ^and ', from.conditions, cond => dumpSqlCondition(dmp, cond)); dmp.putCollection(' ^and ', from.conditions, cond => dumpSqlCondition(dmp, cond));
@ -49,7 +49,7 @@ export function dumpSqlRelation(dmp: SqlDumper, from: Relation) {
} }
export function dumpSqlFromDefinition(dmp: SqlDumper, from: FromDefinition) { export function dumpSqlFromDefinition(dmp: SqlDumper, from: FromDefinition) {
dumpSqlSourceDef(dmp, from.source); dumpSqlSourceDef(dmp, from);
dmp.put(' '); dmp.put(' ');
if (from.relations) from.relations.forEach(rel => dumpSqlRelation(dmp, rel)); if (from.relations) from.relations.forEach(rel => dumpSqlRelation(dmp, rel));
} }

View File

@ -3,4 +3,3 @@ export * from './dumpSqlCommand';
export * from './treeToSql'; export * from './treeToSql';
export * from './dumpSqlSource'; export * from './dumpSqlSource';
export * from './dumpSqlCondition'; export * from './dumpSqlCondition';
export * from './createFunctions';

View File

@ -13,6 +13,8 @@ export interface Select {
range?: RangeDefinition; range?: RangeDefinition;
distinct?: boolean; distinct?: boolean;
selectAll?: boolean; selectAll?: boolean;
orderBy?: OrderByExpression[];
groupBy?: Expression[];
} }
export type Command = Select; export type Command = Select;
@ -47,16 +49,11 @@ export interface Source {
export type JoinType = 'LEFT JOIN' | 'INNER JOIN' | 'RIGHT JOIN'; export type JoinType = 'LEFT JOIN' | 'INNER JOIN' | 'RIGHT JOIN';
export interface Relation { export type Relation = Source & {
source: Source;
conditions: Condition[]; conditions: Condition[];
joinType: JoinType; joinType: JoinType;
} };
export type FromDefinition = Source & { relations?: Relation[] };
export interface FromDefinition {
source: Source;
relations?: Relation[];
}
// export interface Expression { // export interface Expression {
// exprType: "column" | "value" | "string" | "literal" | "count"; // exprType: "column" | "value" | "string" | "literal" | "count";
@ -74,8 +71,6 @@ export interface ValueExpression {
} }
export type Expression = ColumnRefExpression | ValueExpression; export type Expression = ColumnRefExpression | ValueExpression;
export type OrderByExpression = Expression & { direction: 'ASC' | 'DESC' };
export interface ResultField { export type ResultField = Expression & { alias?: string };
expr: ValueExpression | ColumnRefExpression;
alias?: string;
}

View File

@ -1,5 +1,6 @@
export interface SqlDialect { export interface SqlDialect {
rangeSelect?: boolean; rangeSelect?: boolean;
limitSelect?: boolean; limitSelect?: boolean;
offsetFetchRangeSyntax?: boolean;
quoteIdentifier(s: string): string; quoteIdentifier(s: string): string;
} }

View File

@ -1,7 +1,9 @@
import { TableInfo } from "./dbinfo"; import { TableInfo } from "./dbinfo";
import { SqlDialect } from "./dialect";
export interface SqlDumper { export interface SqlDumper {
s: string; s: string;
dialect: SqlDialect;
putRaw(s: string); putRaw(s: string);
put(format: string, ...args); put(format: string, ...args);