mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-29 06:26:00 +00:00
generate update script
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { Command, Insert, Update, Delete, UpdateField, Condition } from '@dbgate/sqltree';
|
||||||
|
|
||||||
export interface ChangeSetItem {
|
export interface ChangeSetItem {
|
||||||
pureName: string;
|
pureName: string;
|
||||||
@@ -100,3 +101,81 @@ export function setChangeSetValue(
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractFields(item: ChangeSetItem): UpdateField[] {
|
||||||
|
return _.keys(item.fields).map(targetColumn => ({
|
||||||
|
targetColumn,
|
||||||
|
exprType: 'value',
|
||||||
|
value: item.fields[targetColumn],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertToSql(item: ChangeSetItem): Insert {
|
||||||
|
return {
|
||||||
|
targetTable: {
|
||||||
|
pureName: item.pureName,
|
||||||
|
schemaName: item.schemaName,
|
||||||
|
},
|
||||||
|
commandType: 'insert',
|
||||||
|
fields: extractFields(item),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractCondition(item: ChangeSetItem): Condition {
|
||||||
|
return {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: _.keys(item.condition).map(columnName => ({
|
||||||
|
conditionType: 'binary',
|
||||||
|
operator: '=',
|
||||||
|
left: {
|
||||||
|
exprType: 'column',
|
||||||
|
columnName,
|
||||||
|
source: {
|
||||||
|
name: {
|
||||||
|
pureName: item.pureName,
|
||||||
|
schemaName: item.schemaName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
exprType: 'value',
|
||||||
|
value: item.condition[columnName],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateToSql(item: ChangeSetItem): Update {
|
||||||
|
return {
|
||||||
|
from: {
|
||||||
|
name: {
|
||||||
|
pureName: item.pureName,
|
||||||
|
schemaName: item.schemaName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commandType: 'update',
|
||||||
|
fields: extractFields(item),
|
||||||
|
where: extractCondition(item),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteToSql(item: ChangeSetItem): Delete {
|
||||||
|
return {
|
||||||
|
from: {
|
||||||
|
name: {
|
||||||
|
pureName: item.pureName,
|
||||||
|
schemaName: item.schemaName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commandType: 'delete',
|
||||||
|
where: extractCondition(item),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeSetToSql(changeSet: ChangeSet): Command[] {
|
||||||
|
return [
|
||||||
|
...changeSet.inserts.map(insertToSql),
|
||||||
|
...changeSet.updates.map(updateToSql),
|
||||||
|
...changeSet.deletes.map(deleteToSql),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { GridConfig, GridCache, GridConfigColumns } from './GridConfig';
|
import { GridConfig, GridCache, GridConfigColumns } from './GridConfig';
|
||||||
import { ForeignKeyInfo, TableInfo, ColumnInfo, DbType } from '@dbgate/types';
|
import { ForeignKeyInfo, TableInfo, ColumnInfo, DbType, EngineDriver } from '@dbgate/types';
|
||||||
import { parseFilter, getFilterType } from '@dbgate/filterparser';
|
import { parseFilter, getFilterType } from '@dbgate/filterparser';
|
||||||
import { filterName } from './filterName';
|
import { filterName } from './filterName';
|
||||||
import { Select, Expression } from '@dbgate/sqltree';
|
import { Select, Expression } from '@dbgate/sqltree';
|
||||||
@@ -44,12 +44,14 @@ export abstract class GridDisplay {
|
|||||||
protected setConfig: (config: GridConfig) => void,
|
protected setConfig: (config: GridConfig) => void,
|
||||||
public cache: GridCache,
|
public cache: GridCache,
|
||||||
protected setCache: (config: GridCache) => void,
|
protected setCache: (config: GridCache) => void,
|
||||||
protected getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>
|
protected getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>,
|
||||||
|
public driver: EngineDriver
|
||||||
) {}
|
) {}
|
||||||
abstract getPageQuery(offset: number, count: number): string;
|
abstract getPageQuery(offset: number, count: number): string;
|
||||||
columns: DisplayColumn[];
|
columns: DisplayColumn[];
|
||||||
baseTable?: TableInfo;
|
baseTable?: TableInfo;
|
||||||
changeSetKeyFields: string[] = null;
|
changeSetKeyFields: string[] = null;
|
||||||
|
|
||||||
setColumnVisibility(uniquePath: string[], isVisible: boolean) {
|
setColumnVisibility(uniquePath: string[], isVisible: boolean) {
|
||||||
const uniqueName = uniquePath.join('.');
|
const uniqueName = uniquePath.join('.');
|
||||||
if (uniquePath.length == 1) {
|
if (uniquePath.length == 1) {
|
||||||
@@ -60,6 +62,10 @@ export abstract class GridDisplay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get engine() {
|
||||||
|
return this.driver.engine;
|
||||||
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.setCache({
|
this.setCache({
|
||||||
...this.cache,
|
...this.cache,
|
||||||
|
|||||||
@@ -7,20 +7,22 @@ import { GridConfig, GridCache } from './GridConfig';
|
|||||||
export class TableGridDisplay extends GridDisplay {
|
export class TableGridDisplay extends GridDisplay {
|
||||||
constructor(
|
constructor(
|
||||||
public table: TableInfo,
|
public table: TableInfo,
|
||||||
public driver: EngineDriver,
|
driver: EngineDriver,
|
||||||
config: GridConfig,
|
config: GridConfig,
|
||||||
setConfig: (config: GridConfig) => void,
|
setConfig: (config: GridConfig) => void,
|
||||||
cache: GridCache,
|
cache: GridCache,
|
||||||
setCache: (config: GridCache) => void,
|
setCache: (config: GridCache) => void,
|
||||||
getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>
|
getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>
|
||||||
) {
|
) {
|
||||||
super(config, setConfig, cache, setCache, getTableInfo);
|
super(config, setConfig, cache, setCache, getTableInfo, driver);
|
||||||
this.columns = this.getDisplayColumns(table, []);
|
this.columns = this.getDisplayColumns(table, []);
|
||||||
this.baseTable = table;
|
this.baseTable = table;
|
||||||
|
if (table && table.columns) {
|
||||||
this.changeSetKeyFields = table.primaryKey
|
this.changeSetKeyFields = table.primaryKey
|
||||||
? table.primaryKey.columns.map(x => x.columnName)
|
? table.primaryKey.columns.map(x => x.columnName)
|
||||||
: table.columns.map(x => x.columnName);
|
: table.columns.map(x => x.columnName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createSelect() {
|
createSelect() {
|
||||||
if (!this.table.columns) return null;
|
if (!this.table.columns) return null;
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ const driver = {
|
|||||||
createDumper() {
|
createDumper() {
|
||||||
return new MsSqlDumper(this);
|
return new MsSqlDumper(this);
|
||||||
},
|
},
|
||||||
dialect
|
dialect,
|
||||||
|
engine: 'mssql',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ const driver = {
|
|||||||
createDumper() {
|
createDumper() {
|
||||||
return new MySqlDumper(this);
|
return new MySqlDumper(this);
|
||||||
},
|
},
|
||||||
dialect
|
dialect,
|
||||||
|
engine: 'mysql',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const driver = {
|
|||||||
return rows;
|
return rows;
|
||||||
},
|
},
|
||||||
dialect,
|
dialect,
|
||||||
|
engine: 'postgres',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
@@ -1,62 +1,111 @@
|
|||||||
import { SqlDumper } from '@dbgate/types';
|
import { SqlDumper } from '@dbgate/types';
|
||||||
import { Command, Select } from './types';
|
import { Command, Select, Update, Delete, Insert } from './types';
|
||||||
import { dumpSqlExpression } from './dumpSqlExpression';
|
import { dumpSqlExpression } from './dumpSqlExpression';
|
||||||
import { dumpSqlFromDefinition } from './dumpSqlSource';
|
import { dumpSqlFromDefinition, dumpSqlSourceRef } from './dumpSqlSource';
|
||||||
import { dumpSqlCondition } from './dumpSqlCondition';
|
import { dumpSqlCondition } from './dumpSqlCondition';
|
||||||
|
|
||||||
export function dumpSqlSelect(dmp: SqlDumper, select: Select) {
|
export function dumpSqlSelect(dmp: SqlDumper, cmd: Select) {
|
||||||
dmp.put('^select ');
|
dmp.put('^select ');
|
||||||
if (select.topRecords) {
|
if (cmd.topRecords) {
|
||||||
dmp.put('^top %s ', select.topRecords);
|
dmp.put('^top %s ', cmd.topRecords);
|
||||||
}
|
}
|
||||||
if (select.distinct) {
|
if (cmd.distinct) {
|
||||||
dmp.put('^distinct ');
|
dmp.put('^distinct ');
|
||||||
}
|
}
|
||||||
if (select.selectAll) {
|
if (cmd.selectAll) {
|
||||||
dmp.put('* ');
|
dmp.put('* ');
|
||||||
}
|
}
|
||||||
if (select.columns) {
|
if (cmd.columns) {
|
||||||
if (select.selectAll) dmp.put('&n,');
|
if (cmd.selectAll) dmp.put('&n,');
|
||||||
dmp.put('&>&n');
|
dmp.put('&>&n');
|
||||||
dmp.putCollection(',&n', select.columns, fld => {
|
dmp.putCollection(',&n', cmd.columns, fld => {
|
||||||
dumpSqlExpression(dmp, fld);
|
dumpSqlExpression(dmp, fld);
|
||||||
if (fld.alias) dmp.put(' ^as %i', fld.alias);
|
if (fld.alias) dmp.put(' ^as %i', fld.alias);
|
||||||
});
|
});
|
||||||
dmp.put('&n&<');
|
dmp.put('&n&<');
|
||||||
}
|
}
|
||||||
dmp.put('^from ');
|
dmp.put('^from ');
|
||||||
dumpSqlFromDefinition(dmp, select.from);
|
dumpSqlFromDefinition(dmp, cmd.from);
|
||||||
if (select.where) {
|
if (cmd.where) {
|
||||||
dmp.put('&n^where ');
|
dmp.put('&n^where ');
|
||||||
dumpSqlCondition(dmp, select.where);
|
dumpSqlCondition(dmp, cmd.where);
|
||||||
dmp.put('&n');
|
dmp.put('&n');
|
||||||
}
|
}
|
||||||
if (select.groupBy) {
|
if (cmd.groupBy) {
|
||||||
dmp.put('&n^group ^by ');
|
dmp.put('&n^group ^by ');
|
||||||
dmp.putCollection(', ', select.groupBy, expr => dumpSqlExpression(dmp, expr));
|
dmp.putCollection(', ', cmd.groupBy, expr => dumpSqlExpression(dmp, expr));
|
||||||
dmp.put('&n');
|
dmp.put('&n');
|
||||||
}
|
}
|
||||||
if (select.orderBy) {
|
if (cmd.orderBy) {
|
||||||
dmp.put('&n^order ^by ');
|
dmp.put('&n^order ^by ');
|
||||||
dmp.putCollection(', ', select.orderBy, expr => {
|
dmp.putCollection(', ', cmd.orderBy, expr => {
|
||||||
dumpSqlExpression(dmp, expr);
|
dumpSqlExpression(dmp, expr);
|
||||||
dmp.put(' %k', expr.direction);
|
dmp.put(' %k', expr.direction);
|
||||||
});
|
});
|
||||||
dmp.put('&n');
|
dmp.put('&n');
|
||||||
}
|
}
|
||||||
if (select.range) {
|
if (cmd.range) {
|
||||||
if (dmp.dialect.offsetFetchRangeSyntax) {
|
if (dmp.dialect.offsetFetchRangeSyntax) {
|
||||||
dmp.put('^offset %s ^rows ^fetch ^next %s ^rows ^only', select.range.offset, select.range.limit);
|
dmp.put('^offset %s ^rows ^fetch ^next %s ^rows ^only', cmd.range.offset, cmd.range.limit);
|
||||||
} else {
|
} else {
|
||||||
dmp.put('^limit %s ^offset %s ', select.range.limit, select.range.offset);
|
dmp.put('^limit %s ^offset %s ', cmd.range.limit, cmd.range.offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dumpSqlCommand(dmp: SqlDumper, command: Command) {
|
export function dumpSqlUpdate(dmp: SqlDumper, cmd: Update) {
|
||||||
switch (command.commandType) {
|
dmp.put('^update ');
|
||||||
|
dumpSqlSourceRef(dmp, cmd.from);
|
||||||
|
|
||||||
|
dmp.put('&n^set ');
|
||||||
|
dmp.put('&>');
|
||||||
|
dmp.putCollection(', ', cmd.fields, col => {
|
||||||
|
dmp.put('%i=', col.targetColumn);
|
||||||
|
dumpSqlExpression(dmp, col);
|
||||||
|
});
|
||||||
|
dmp.put('&<');
|
||||||
|
|
||||||
|
if (cmd.where) {
|
||||||
|
dmp.put('&n^where ');
|
||||||
|
dumpSqlCondition(dmp, cmd.where);
|
||||||
|
dmp.put('&n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dumpSqlDelete(dmp: SqlDumper, cmd: Delete) {
|
||||||
|
dmp.put('^delete ');
|
||||||
|
dumpSqlSourceRef(dmp, cmd.from);
|
||||||
|
|
||||||
|
if (cmd.where) {
|
||||||
|
dmp.put('&n^where ');
|
||||||
|
dumpSqlCondition(dmp, cmd.where);
|
||||||
|
dmp.put('&n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dumpSqlInsert(dmp: SqlDumper, cmd: Insert) {
|
||||||
|
dmp.put(
|
||||||
|
'^insert ^into %f (%,i) ^values (',
|
||||||
|
cmd.targetTable,
|
||||||
|
cmd.fields.map(x => x.targetColumn)
|
||||||
|
);
|
||||||
|
dmp.putCollection(',', cmd.fields, x => dumpSqlExpression(dmp, x));
|
||||||
|
dmp.put(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dumpSqlCommand(dmp: SqlDumper, cmd: Command) {
|
||||||
|
switch (cmd.commandType) {
|
||||||
case 'select':
|
case 'select':
|
||||||
dumpSqlSelect(dmp, command);
|
dumpSqlSelect(dmp, cmd);
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
dumpSqlUpdate(dmp, cmd);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
dumpSqlDelete(dmp, cmd);
|
||||||
|
break;
|
||||||
|
case 'insert':
|
||||||
|
dumpSqlInsert(dmp, cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export * from './types';
|
export * from './types';
|
||||||
export * from './dumpSqlCommand';
|
export * from './dumpSqlCommand';
|
||||||
export * from './treeToSql';
|
export * from './utility';
|
||||||
export * from './dumpSqlSource';
|
export * from './dumpSqlSource';
|
||||||
export * from './dumpSqlCondition';
|
export * from './dumpSqlCondition';
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,31 @@ export interface Select {
|
|||||||
where?: Condition;
|
where?: Condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Command = Select;
|
export type UpdateField = Expression & { targetColumn: string };
|
||||||
|
|
||||||
|
export interface Update {
|
||||||
|
commandType: 'update';
|
||||||
|
fields: UpdateField[];
|
||||||
|
from: FromDefinition;
|
||||||
|
where?: Condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Delete {
|
||||||
|
commandType: 'delete';
|
||||||
|
from: FromDefinition;
|
||||||
|
where?: Condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Insert {
|
||||||
|
commandType: 'insert';
|
||||||
|
fields: UpdateField[];
|
||||||
|
targetTable: {
|
||||||
|
schemaName: string;
|
||||||
|
pureName: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Command = Select | Update | Delete | Insert;
|
||||||
|
|
||||||
// export interface Condition {
|
// export interface Condition {
|
||||||
// conditionType: "eq" | "not" | "binary";
|
// conditionType: "eq" | "not" | "binary";
|
||||||
|
|||||||
18
packages/sqltree/src/utility.ts
Normal file
18
packages/sqltree/src/utility.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { EngineDriver, SqlDumper } from '@dbgate/types';
|
||||||
|
import { Command } from './types';
|
||||||
|
import { dumpSqlCommand } from './dumpSqlCommand';
|
||||||
|
|
||||||
|
export function treeToSql<T>(driver: EngineDriver, object: T, func: (dmp: SqlDumper, obj: T) => void) {
|
||||||
|
const dmp = driver.createDumper();
|
||||||
|
func(dmp, object);
|
||||||
|
return dmp.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function scriptToSql(driver: EngineDriver, script: Command[]): string {
|
||||||
|
const dmp = driver.createDumper();
|
||||||
|
for (const cmd of script) {
|
||||||
|
dumpSqlCommand(dmp, cmd);
|
||||||
|
dmp.endCommand();
|
||||||
|
}
|
||||||
|
return dmp.s;
|
||||||
|
}
|
||||||
1
packages/types/engines.d.ts
vendored
1
packages/types/engines.d.ts
vendored
@@ -4,6 +4,7 @@ import { SqlDumper } from "./dumper";
|
|||||||
import { DatabaseInfo } from "./dbinfo";
|
import { DatabaseInfo } from "./dbinfo";
|
||||||
|
|
||||||
export interface EngineDriver {
|
export interface EngineDriver {
|
||||||
|
engine: string;
|
||||||
connect(nativeModules, { server, port, user, password, database }): any;
|
connect(nativeModules, { server, port, user, password, database }): any;
|
||||||
query(pool: any, sql: string): Promise<QueryResult>;
|
query(pool: any, sql: string): Promise<QueryResult>;
|
||||||
getVersion(pool: any): Promise<{ version: string }>;
|
getVersion(pool: any): Promise<{ version: string }>;
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import React from 'react';
|
|
||||||
import { ColumnIcon, SequenceIcon } from '../icons';
|
import { ColumnIcon, SequenceIcon } from '../icons';
|
||||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
|
||||||
import showModal from '../modals/showModal';
|
|
||||||
import ConnectionModal from '../modals/ConnectionModal';
|
|
||||||
import axios from '../utility/axios';
|
|
||||||
import { openNewTab } from '../utility/common';
|
|
||||||
import { useSetOpenedTabs } from '../utility/globalState';
|
|
||||||
|
|
||||||
/** @param columnProps {import('@dbgate/types').ColumnInfo} */
|
/** @param columnProps {import('@dbgate/types').ColumnInfo} */
|
||||||
function getColumnIcon(columnProps) {
|
function getColumnIcon(columnProps) {
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import React from 'react';
|
|
||||||
import { PrimaryKeyIcon, ForeignKeyIcon } from '../icons';
|
import { PrimaryKeyIcon, ForeignKeyIcon } from '../icons';
|
||||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
|
||||||
import showModal from '../modals/showModal';
|
|
||||||
import ConnectionModal from '../modals/ConnectionModal';
|
|
||||||
import axios from '../utility/axios';
|
|
||||||
import { openNewTab } from '../utility/common';
|
|
||||||
import { useSetOpenedTabs } from '../utility/globalState';
|
|
||||||
|
|
||||||
/** @param props {import('@dbgate/types').ConstraintInfo} */
|
/** @param props {import('@dbgate/types').ConstraintInfo} */
|
||||||
function getConstraintIcon(props) {
|
function getConstraintIcon(props) {
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TableIcon } from '../icons';
|
import { TableIcon } from '../icons';
|
||||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
||||||
import showModal from '../modals/showModal';
|
|
||||||
import ConnectionModal from '../modals/ConnectionModal';
|
|
||||||
import axios from '../utility/axios';
|
|
||||||
import { openNewTab } from '../utility/common';
|
import { openNewTab } from '../utility/common';
|
||||||
import { useSetOpenedTabs } from '../utility/globalState';
|
|
||||||
import getConnectionInfo from '../utility/getConnectionInfo';
|
import getConnectionInfo from '../utility/getConnectionInfo';
|
||||||
import fullDisplayName from '../utility/fullDisplayName';
|
import fullDisplayName from '../utility/fullDisplayName';
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ import keycodes from '../utility/keycodes';
|
|||||||
import InplaceEditor from './InplaceEditor';
|
import InplaceEditor from './InplaceEditor';
|
||||||
import DataGridRow from './DataGridRow';
|
import DataGridRow from './DataGridRow';
|
||||||
import { countColumnSizes, countVisibleRealColumns } from './gridutil';
|
import { countColumnSizes, countVisibleRealColumns } from './gridutil';
|
||||||
|
import useModalState from '../modals/useModalState';
|
||||||
|
import ConfirmSqlModal from '../modals/ConfirmSqlModal';
|
||||||
|
import { changeSetToSql } from '@dbgate/datalib';
|
||||||
|
import { scriptToSql } from '@dbgate/sqltree';
|
||||||
|
|
||||||
const GridContainer = styled.div`
|
const GridContainer = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -162,6 +166,8 @@ export default function DataGridCore(props) {
|
|||||||
const [tableBodyRef] = useDimensions();
|
const [tableBodyRef] = useDimensions();
|
||||||
const [containerRef, { height: containerHeight, width: containerWidth }] = useDimensions();
|
const [containerRef, { height: containerHeight, width: containerWidth }] = useDimensions();
|
||||||
const [tableRef, { height: tableHeight, width: tableWidth }, tableElement] = useDimensions();
|
const [tableRef, { height: tableHeight, width: tableWidth }, tableElement] = useDimensions();
|
||||||
|
const confirmSqlModalState = useModalState();
|
||||||
|
const [confirmSql, setConfirmSql] = React.useState('');
|
||||||
|
|
||||||
const columnSizes = React.useMemo(() => countColumnSizes(loadedRows, columns, containerWidth, display), [
|
const columnSizes = React.useMemo(() => countColumnSizes(loadedRows, columns, containerWidth, display), [
|
||||||
loadedRows,
|
loadedRows,
|
||||||
@@ -221,7 +227,8 @@ export default function DataGridCore(props) {
|
|||||||
[columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns]
|
[columnSizes, firstVisibleColumnScrollIndex, gridScrollAreaWidth, columns]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cellIsSelected = React.useCallback((row, col) => {
|
const cellIsSelected = React.useCallback(
|
||||||
|
(row, col) => {
|
||||||
const [currentRow, currentCol] = currentCell;
|
const [currentRow, currentCol] = currentCell;
|
||||||
if (row == currentRow && col == currentCol) return true;
|
if (row == currentRow && col == currentCol) return true;
|
||||||
for (const [selectedRow, selectedCol] of selectedCells) {
|
for (const [selectedRow, selectedCol] of selectedCells) {
|
||||||
@@ -231,8 +238,9 @@ export default function DataGridCore(props) {
|
|||||||
if (selectedRow == 'header' && selectedCol == 'header') return true;
|
if (selectedRow == 'header' && selectedCol == 'header') return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}, [currentCell, selectedCells]);
|
},
|
||||||
|
[currentCell, selectedCells]
|
||||||
|
);
|
||||||
|
|
||||||
if (!loadedRows || !columns) return null;
|
if (!loadedRows || !columns) return null;
|
||||||
const rowCountNewIncluded = loadedRows.length;
|
const rowCountNewIncluded = loadedRows.length;
|
||||||
@@ -297,6 +305,13 @@ export default function DataGridCore(props) {
|
|||||||
setvScrollValueToSetDate(new Date());
|
setvScrollValueToSetDate(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSave() {
|
||||||
|
const script = changeSetToSql(changeSet);
|
||||||
|
const sql = scriptToSql(display.driver, script);
|
||||||
|
setConfirmSql(sql);
|
||||||
|
confirmSqlModalState.open();
|
||||||
|
}
|
||||||
|
|
||||||
function handleGridKeyDown(event) {
|
function handleGridKeyDown(event) {
|
||||||
if (
|
if (
|
||||||
!event.ctrlKey &&
|
!event.ctrlKey &&
|
||||||
@@ -310,6 +325,12 @@ export default function DataGridCore(props) {
|
|||||||
// console.log('event', event.nativeEvent);
|
// console.log('event', event.nativeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == keycodes.s && event.ctrlKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
handleSave();
|
||||||
|
// this.saveAndFocus();
|
||||||
|
}
|
||||||
|
|
||||||
const moved = handleCursorMove(event);
|
const moved = handleCursorMove(event);
|
||||||
|
|
||||||
if (moved) {
|
if (moved) {
|
||||||
@@ -555,6 +576,7 @@ export default function DataGridCore(props) {
|
|||||||
onScroll={handleRowScroll}
|
onScroll={handleRowScroll}
|
||||||
viewportRatio={visibleRowCountUpperBound / rowCountNewIncluded}
|
viewportRatio={visibleRowCountUpperBound / rowCountNewIncluded}
|
||||||
/>
|
/>
|
||||||
|
<ConfirmSqlModal modalState={confirmSqlModalState} sql={confirmSql} engine={display.engine} />
|
||||||
</GridContainer>
|
</GridContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
31
packages/web/src/modals/ConfirmSqlModal.js
Normal file
31
packages/web/src/modals/ConfirmSqlModal.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import axios from '../utility/axios';
|
||||||
|
import ModalBase from './ModalBase';
|
||||||
|
import { FormRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||||
|
import { TextField } from '../utility/inputs';
|
||||||
|
import { Formik, Form } from 'formik';
|
||||||
|
import SqlEditor from '../sqleditor/SqlEditor';
|
||||||
|
// import FormikForm from '../utility/FormikForm';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const SqlWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
height: 30vh;
|
||||||
|
width: 40vw;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function ConfirmSqlModal({ modalState, sql, engine }) {
|
||||||
|
return (
|
||||||
|
<ModalBase modalState={modalState}>
|
||||||
|
<h2>Save changes</h2>
|
||||||
|
<SqlWrapper>
|
||||||
|
<SqlEditor value={sql} engine={engine} />
|
||||||
|
</SqlWrapper>
|
||||||
|
|
||||||
|
<FormRow>
|
||||||
|
<input type="button" value="OK" onClick={modalState.close} />
|
||||||
|
<input type="button" value="Close" onClick={modalState.close} />
|
||||||
|
</FormRow>
|
||||||
|
</ModalBase>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user