messages from query

This commit is contained in:
Jan Prochazka
2020-04-10 13:49:41 +02:00
parent f01bf8a605
commit aa2eae2696
6 changed files with 89 additions and 38 deletions

View File

@@ -9,23 +9,44 @@ module.exports = {
/** @type {import('@dbgate/types').OpenedSession[]} */ /** @type {import('@dbgate/types').OpenedSession[]} */
opened: [], opened: [],
handle_error(sesid, props) { // handle_error(sesid, props) {
const { error } = props; // const { error } = props;
console.log(`Error in database session ${sesid}: ${error}`); // console.log(`Error in database session ${sesid}`, error);
}, // this.dispatchMessage(sesid, {
// severity: 'error',
// message: error && error.toString(),
// });
// },
// handle_row(sesid, props) { // handle_row(sesid, props) {
// const { row } = props; // const { row } = props;
// socket.emit('sessionRow', row); // socket.emit('sessionRow', row);
// }, // },
dispatchMessage(sesid, message) {
if (_.isString(message)) {
socket.emit(`session-info-${sesid}`, {
message,
time: new Date(),
severity: 'info',
});
}
if (_.isPlainObject(message)) {
socket.emit(`session-info-${sesid}`, {
time: new Date(),
severity: 'info',
...message,
});
}
},
handle_info(sesid, props) { handle_info(sesid, props) {
const { info } = props; const { info } = props;
socket.emit(`session-info-${sesid}`, info); this.dispatchMessage(sesid, info);
}, },
handle_done(sesid) { handle_done(sesid) {
socket.emit(`session-done-${sesid}`); socket.emit(`session-done-${sesid}`);
this.dispatchMessage(sesid, 'Query execution finished');
}, },
handle_recordset(sesid, props) { handle_recordset(sesid, props) {
@@ -62,6 +83,7 @@ module.exports = {
} }
console.log(`Processing query, sesid=${sesid}, sql=${sql}`); console.log(`Processing query, sesid=${sesid}, sql=${sql}`);
this.dispatchMessage(sesid, 'Query execution started');
session.subprocess.send({ msgtype: 'executeQuery', sql }); session.subprocess.send({ msgtype: 'executeQuery', sql });
return { state: 'ok' }; return { state: 'ok' };

View File

@@ -14,7 +14,7 @@ class StreamHandler {
constructor() { constructor() {
this.recordset = this.recordset.bind(this); this.recordset = this.recordset.bind(this);
this.row = this.row.bind(this); this.row = this.row.bind(this);
this.error = this.error.bind(this); // this.error = this.error.bind(this);
this.done = this.done.bind(this); this.done = this.done.bind(this);
this.info = this.info.bind(this); this.info = this.info.bind(this);
} }
@@ -38,9 +38,9 @@ class StreamHandler {
// console.log('ACCEPT ROW', row); // console.log('ACCEPT ROW', row);
this.currentStream.write(JSON.stringify(row) + '\n'); this.currentStream.write(JSON.stringify(row) + '\n');
} }
error(error) { // error(error) {
process.send({ msgtype: 'error', error }); // process.send({ msgtype: 'error', error });
} // }
done(result) { done(result) {
this.closeCurrentStream(); this.closeCurrentStream();
process.send({ msgtype: 'done', result }); process.send({ msgtype: 'done', result });
@@ -91,7 +91,14 @@ function start() {
try { try {
await handleMessage(message); await handleMessage(message);
} catch (e) { } catch (e) {
process.send({ msgtype: 'error', error: e.message }); process.send({
msgtype: 'info',
info: {
message: e.message,
severity: 'error',
},
});
//process.send({ msgtype: 'error', error: e.message });
} }
}); });
} }

View File

@@ -74,13 +74,14 @@ export abstract class GridDisplay {
} }
reload() { reload() {
this.setCache(cache => ({ this.setCache((cache) => ({
...cache, ...cache,
refreshTime: new Date().getTime(), refreshTime: new Date().getTime(),
})); }));
} }
includeInColumnSet(field: keyof GridConfigColumns, uniqueName: string, isIncluded: boolean) { includeInColumnSet(field: keyof GridConfigColumns, uniqueName: string, isIncluded: boolean) {
// console.log('includeInColumnSet', field, uniqueName, isIncluded);
if (isIncluded) { if (isIncluded) {
this.setConfig({ this.setConfig({
...this.config, ...this.config,
@@ -89,7 +90,7 @@ export abstract class GridDisplay {
} else { } else {
this.setConfig({ this.setConfig({
...this.config, ...this.config,
[field]: (this.config[field] || []).filter(x => x != uniqueName), [field]: (this.config[field] || []).filter((x) => x != uniqueName),
}); });
} }
} }
@@ -104,12 +105,12 @@ export abstract class GridDisplay {
hideAllColumns() { hideAllColumns() {
this.setConfig({ this.setConfig({
...this.config, ...this.config,
hiddenColumns: this.columns.map(x => x.uniqueName), hiddenColumns: this.columns.map((x) => x.uniqueName),
}); });
} }
get hiddenColumnIndexes() { get hiddenColumnIndexes() {
return (this.config.hiddenColumns || []).map(x => _.findIndex(this.columns, y => y.uniqueName == x)); return (this.config.hiddenColumns || []).map((x) => _.findIndex(this.columns, (y) => y.uniqueName == x));
} }
enrichExpandedColumns(list: DisplayColumn[]): DisplayColumn[] { enrichExpandedColumns(list: DisplayColumn[]): DisplayColumn[] {
@@ -134,8 +135,8 @@ export abstract class GridDisplay {
requireFkTarget(column: DisplayColumn) { requireFkTarget(column: DisplayColumn) {
const { uniqueName, foreignKey } = column; const { uniqueName, foreignKey } = column;
this.getTableInfo({ schemaName: foreignKey.refSchemaName, pureName: foreignKey.refTableName }).then(table => { this.getTableInfo({ schemaName: foreignKey.refSchemaName, pureName: foreignKey.refTableName }).then((table) => {
this.setCache(cache => ({ this.setCache((cache) => ({
...cache, ...cache,
tables: { tables: {
...cache.tables, ...cache.tables,
@@ -146,6 +147,7 @@ export abstract class GridDisplay {
} }
isColumnChecked(column: DisplayColumn) { isColumnChecked(column: DisplayColumn) {
// console.log('isColumnChecked', column, this.config.hiddenColumns);
return column.uniquePath.length == 1 return column.uniquePath.length == 1
? !this.config.hiddenColumns.includes(column.uniqueName) ? !this.config.hiddenColumns.includes(column.uniqueName)
: this.config.addedColumns.includes(column.uniqueName); : this.config.addedColumns.includes(column.uniqueName);
@@ -162,10 +164,10 @@ export abstract class GridDisplay {
headerText: uniquePath.length == 1 ? col.columnName : `${table.pureName}.${col.columnName}`, headerText: uniquePath.length == 1 ? col.columnName : `${table.pureName}.${col.columnName}`,
uniqueName, uniqueName,
uniquePath, uniquePath,
isPrimaryKey: table.primaryKey && !!table.primaryKey.columns.find(x => x.columnName == col.columnName), isPrimaryKey: table.primaryKey && !!table.primaryKey.columns.find((x) => x.columnName == col.columnName),
foreignKey: foreignKey:
table.foreignKeys && table.foreignKeys &&
table.foreignKeys.find(fk => fk.columns.length == 1 && fk.columns[0].columnName == col.columnName), table.foreignKeys.find((fk) => fk.columns.length == 1 && fk.columns[0].columnName == col.columnName),
}; };
} }
@@ -231,7 +233,7 @@ export abstract class GridDisplay {
addReferenceToSelect(select: Select, parentAlias: string, column: DisplayColumn) { addReferenceToSelect(select: Select, parentAlias: string, column: DisplayColumn) {
const childAlias = `${column.uniqueName}_ref`; const childAlias = `${column.uniqueName}_ref`;
if ((select.from.relations || []).find(x => x.alias == childAlias)) return; if ((select.from.relations || []).find((x) => x.alias == childAlias)) return;
const table = this.cache.tables[column.uniqueName]; const table = this.cache.tables[column.uniqueName];
select.from.relations = [ select.from.relations = [
...(select.from.relations || []), ...(select.from.relations || []),
@@ -265,7 +267,7 @@ export abstract class GridDisplay {
if (column.foreignKey) { if (column.foreignKey) {
const table = this.cache.tables[column.uniqueName]; const table = this.cache.tables[column.uniqueName];
if (table) { if (table) {
const hintColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char')); const hintColumn = table.columns.find((x) => x?.dataType?.toLowerCase()?.includes('char'));
if (hintColumn) { if (hintColumn) {
const parentUniqueName = column.uniquePath.slice(0, -1).join('.'); const parentUniqueName = column.uniquePath.slice(0, -1).join('.');
this.addReferenceToSelect(select, parentUniqueName ? `${parentUniqueName}_ref` : 'basetbl', column); this.addReferenceToSelect(select, parentUniqueName ? `${parentUniqueName}_ref` : 'basetbl', column);
@@ -315,9 +317,9 @@ export abstract class GridDisplay {
applySortOnSelect(select: Select, displayedColumnInfo: DisplayedColumnInfo) { applySortOnSelect(select: Select, displayedColumnInfo: DisplayedColumnInfo) {
if (this.config.sort?.length > 0) { if (this.config.sort?.length > 0) {
select.orderBy = this.config.sort select.orderBy = this.config.sort
.map(col => ({ ...col, dispInfo: displayedColumnInfo[col.uniqueName] })) .map((col) => ({ ...col, dispInfo: displayedColumnInfo[col.uniqueName] }))
.filter(col => col.dispInfo) .filter((col) => col.dispInfo)
.map(col => ({ .map((col) => ({
exprType: 'column', exprType: 'column',
columnName: col.dispInfo.columnName, columnName: col.dispInfo.columnName,
direction: col.order, direction: col.order,
@@ -329,8 +331,8 @@ export abstract class GridDisplay {
getDisplayColumns(table: TableInfo, parentPath: string[]) { getDisplayColumns(table: TableInfo, parentPath: string[]) {
return ( return (
table?.columns table?.columns
?.map(col => this.getDisplayColumn(table, col, parentPath)) ?.map((col) => this.getDisplayColumn(table, col, parentPath))
?.map(col => ({ ?.map((col) => ({
...col, ...col,
isChecked: this.isColumnChecked(col), isChecked: this.isColumnChecked(col),
hintColumnName: col.foreignKey ? `hint_${col.uniqueName}` : null, hintColumnName: col.foreignKey ? `hint_${col.uniqueName}` : null,
@@ -339,11 +341,11 @@ export abstract class GridDisplay {
} }
getColumns(columnFilter) { getColumns(columnFilter) {
return this.enrichExpandedColumns(this.columns.filter(col => filterName(columnFilter, col.columnName))); return this.enrichExpandedColumns(this.columns.filter((col) => filterName(columnFilter, col.columnName)));
} }
getGridColumns() { getGridColumns() {
return this.getColumns(null).filter(x => this.isColumnChecked(x)); return this.getColumns(null).filter((x) => this.isColumnChecked(x));
} }
isExpandedColumn(uniqueName: string) { isExpandedColumn(uniqueName: string) {
@@ -378,7 +380,7 @@ export abstract class GridDisplay {
} }
getSortOrder(uniqueName) { getSortOrder(uniqueName) {
return this.config.sort.find(x => x.uniqueName == uniqueName)?.order; return this.config.sort.find((x) => x.uniqueName == uniqueName)?.order;
} }
get filterCount() { get filterCount() {
@@ -399,7 +401,7 @@ export abstract class GridDisplay {
} }
getChangeSetField(row, uniqueName, insertedRowIndex): ChangeSetFieldDefinition { getChangeSetField(row, uniqueName, insertedRowIndex): ChangeSetFieldDefinition {
const col = this.columns.find(x => x.uniqueName == uniqueName); const col = this.columns.find((x) => x.uniqueName == uniqueName);
if (!col) return null; if (!col) return null;
if (!this.baseTable) return null; if (!this.baseTable) return null;
if (this.baseTable.pureName != col.pureName || this.baseTable.schemaName != col.schemaName) return null; if (this.baseTable.pureName != col.pureName || this.baseTable.schemaName != col.schemaName) return null;

View File

@@ -12,13 +12,19 @@ export class JslGridDisplay extends GridDisplay {
setCache: ChangeCacheFunc setCache: ChangeCacheFunc
) { ) {
super(config, setConfig, cache, setCache, null, null); super(config, setConfig, cache, setCache, null, null);
this.columns = columns.map((col) => ({
this.columns = columns
.map((col) => ({
columnName: col.columnName, columnName: col.columnName,
headerText: col.columnName, headerText: col.columnName,
uniqueName: col.columnName, uniqueName: col.columnName,
uniquePath: [col.columnName], uniquePath: [col.columnName],
notNull: col.notNull, notNull: col.notNull,
autoIncrement: col.autoIncrement, autoIncrement: col.autoIncrement,
}))
?.map((col) => ({
...col,
isChecked: this.isColumnChecked(col),
})); }));
} }
} }

View File

@@ -63,6 +63,7 @@ const driver = {
line: lineNumber, line: lineNumber,
procedure: procName, procedure: procName,
time: new Date(), time: new Date(),
severity: 'info',
}); });
}; };
@@ -79,10 +80,21 @@ const driver = {
options.recordset(extractColumns(columns)); options.recordset(extractColumns(columns));
}; };
const handleError = (error) => {
const { message, lineNumber, procName } = error;
options.info({
message,
line: lineNumber,
procedure: procName,
time: new Date(),
severity: 'error',
});
};
request.stream = true; request.stream = true;
request.on('recordset', handleRecordset); request.on('recordset', handleRecordset);
request.on('row', handleRow); request.on('row', handleRow);
request.on('error', options.error); request.on('error', handleError);
request.on('done', handleDone); request.on('done', handleDone);
request.on('info', handleInfo); request.on('info', handleInfo);
request.query(sql); request.query(sql);

View File

@@ -14,6 +14,8 @@ export default function JslDataGrid({ jslid }) {
const display = React.useMemo(() => new JslGridDisplay(jslid, columns, config, setConfig, cache, setCache), [ const display = React.useMemo(() => new JslGridDisplay(jslid, columns, config, setConfig, cache, setCache), [
jslid, jslid,
columns, columns,
config,
cache,
]); ]);
return <DataGrid display={display} jslid={jslid} />; return <DataGrid display={display} jslid={jslid} />;