mirror of https://github.com/Fabio286/antares.git
fix(PostgreSQL): various issues in query results
This commit is contained in:
parent
d465e18dba
commit
fccfe92453
|
@ -73,6 +73,7 @@
|
||||||
"mysql2": "^2.2.5",
|
"mysql2": "^2.2.5",
|
||||||
"node-sql-parser": "^3.1.0",
|
"node-sql-parser": "^3.1.0",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
|
"pgsql-ast-parser": "^7.0.2",
|
||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"spectre.css": "^0.5.9",
|
"spectre.css": "^0.5.9",
|
||||||
"v-mask": "^2.2.4",
|
"v-mask": "^2.2.4",
|
||||||
|
|
|
@ -19,7 +19,7 @@ module.exports = {
|
||||||
schedulers: false,
|
schedulers: false,
|
||||||
// Settings
|
// Settings
|
||||||
databaseEdit: false,
|
databaseEdit: false,
|
||||||
tableSettings: false,
|
tableSettings: true,
|
||||||
viewSettings: false,
|
viewSettings: false,
|
||||||
triggerSettings: false,
|
triggerSettings: false,
|
||||||
routineSettings: false,
|
routineSettings: false,
|
||||||
|
|
|
@ -118,7 +118,7 @@ module.exports = [
|
||||||
group: 'time',
|
group: 'time',
|
||||||
types: [
|
types: [
|
||||||
{
|
{
|
||||||
name: 'TIMESTAMP',
|
name: 'TIMESTAMP WITHOUT TIME ZONE',
|
||||||
length: false,
|
length: false,
|
||||||
unsigned: false
|
unsigned: false
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = [
|
module.exports = [
|
||||||
'PRIMARY',
|
'PRIMARY',
|
||||||
'INDEX',
|
'KEY',
|
||||||
'UNIQUE'
|
'UNIQUE'
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import pg, { Pool, Client, types } from 'pg';
|
import pg, { Pool, Client, types } from 'pg';
|
||||||
import { Parser } from 'node-sql-parser';
|
import { parse } from 'pgsql-ast-parser';
|
||||||
import { AntaresCore } from '../AntaresCore';
|
import { AntaresCore } from '../AntaresCore';
|
||||||
import dataTypes from 'common/data-types/postgresql';
|
import dataTypes from 'common/data-types/postgresql';
|
||||||
|
|
||||||
|
@ -322,6 +322,27 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Number} id
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
async getTableByIDs (ids) {
|
||||||
|
const { rows } = await this.raw(`
|
||||||
|
SELECT relid AS tableid, relname, schemaname FROM pg_statio_all_tables WHERE relid IN (${ids})
|
||||||
|
UNION
|
||||||
|
SELECT pg_class.oid AS tableid,relname, nspname AS schemaname FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE pg_class.oid IN (${ids})
|
||||||
|
`);
|
||||||
|
|
||||||
|
return rows.reduce((acc, curr) => {
|
||||||
|
acc[curr.tableid] = {
|
||||||
|
table: curr.relname,
|
||||||
|
schema: curr.schemaname
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
* @param {String} params.schema
|
* @param {String} params.schema
|
||||||
|
@ -330,34 +351,28 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async getKeyUsage ({ schema, table }) {
|
async getKeyUsage ({ schema, table }) {
|
||||||
const { rows } = await this
|
const { rows } = await this.raw(`
|
||||||
.select('*')
|
SELECT *
|
||||||
.schema('information_schema')
|
FROM information_schema.key_column_usage
|
||||||
.from('key_column_usage')
|
JOIN information_schema.referential_constraints ON
|
||||||
.where({ TABLE_SCHEMA: `= '${schema}'`, TABLE_NAME: `= '${table}'` })
|
referential_constraints.constraint_name = key_column_usage.constraint_name
|
||||||
.run();
|
WHERE table_schema = '${schema}'
|
||||||
|
AND table_name = '${table}'
|
||||||
const { rows: extras } = await this
|
`);
|
||||||
.select('*')
|
|
||||||
.schema('information_schema')
|
|
||||||
.from('referential_constraints')
|
|
||||||
.where({ constraint_schema: `= '${schema}'`, constraint_name: `= '${table}'` })
|
|
||||||
.run();
|
|
||||||
|
|
||||||
return rows.map(field => {
|
return rows.map(field => {
|
||||||
const extra = extras.find(x => x.CONSTRAINT_NAME === field.CONSTRAINT_NAME);
|
|
||||||
return {
|
return {
|
||||||
schema: field.TABLE_SCHEMA,
|
schema: field.table_schema,
|
||||||
table: field.TABLE_NAME,
|
table: field.table_name,
|
||||||
field: field.COLUMN_NAME,
|
field: field.column_name,
|
||||||
position: field.ORDINAL_POSITION,
|
position: field.ordinal_position,
|
||||||
constraintPosition: field.POSITION_IN_UNIQUE_CONSTRAINT,
|
constraintPosition: field.position_inUnique_constraint,
|
||||||
constraintName: field.CONSTRAINT_NAME,
|
constraintName: field.constraint_name,
|
||||||
refSchema: field.REFERENCED_TABLE_SCHEMA,
|
refSchema: field.REFERENCED_TABLE_SCHEMA,
|
||||||
refTable: field.REFERENCED_TABLE_NAME,
|
refTable: field.REFERENCED_TABLE_NAME,
|
||||||
refField: field.REFERENCED_COLUMN_NAME,
|
refField: field.REFERENCED_COLUMN_NAME,
|
||||||
onUpdate: extra ? extra.UPDATE_RULE : '',
|
onUpdate: field.update_rule,
|
||||||
onDelete: extra ? extra.DELETE_RULE : ''
|
onDelete: field.delete_rule
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1228,22 +1243,38 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
let keysArr = [];
|
let keysArr = [];
|
||||||
|
|
||||||
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
|
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
|
||||||
this._connection.query({ text: query }, async (err, res) => {
|
this._connection.query({
|
||||||
|
rowMode: args.nest ? 'array' : null,
|
||||||
|
text: query
|
||||||
|
}, async (err, res) => {
|
||||||
timeStop = new Date();
|
timeStop = new Date();
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
reject(err);
|
reject(err);
|
||||||
else {
|
else {
|
||||||
const { rows, fields } = res;
|
|
||||||
const queryResult = rows;
|
|
||||||
const parser = new Parser();
|
|
||||||
let ast;
|
let ast;
|
||||||
try {
|
|
||||||
ast = parser.astify(query);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
[ast] = parse(query);
|
||||||
}
|
}
|
||||||
|
catch (err) {}
|
||||||
|
|
||||||
|
const { rows, fields } = res;
|
||||||
|
let queryResult;
|
||||||
|
if (args.nest) {
|
||||||
|
const tablesID = [...new Set(fields.map(field => field.tableID))].toString();
|
||||||
|
const tablesInfo = await this.getTableByIDs(tablesID);
|
||||||
|
|
||||||
|
queryResult = rows.map(row => {
|
||||||
|
return row.reduce((acc, curr, i) => {
|
||||||
|
const table = tablesInfo[fields[i].tableID].table;
|
||||||
|
acc[`${table}.${fields[i].name}`] = curr;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
queryResult = rows;
|
||||||
|
|
||||||
let remappedFields = fields
|
let remappedFields = fields
|
||||||
? fields.map(field => {
|
? fields.map(field => {
|
||||||
|
@ -1251,26 +1282,24 @@ export class PostgreSQLClient extends AntaresCore {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
...field,
|
||||||
name: field.name,
|
name: field.name,
|
||||||
alias: field.name,
|
alias: field.name,
|
||||||
schema: ast && ast.from ? ast.from[0].db : this._schema,
|
schema: ast && ast.from && 'schema' in ast.from[0] ? ast.from[0].schema : this._schema,
|
||||||
table: ast && ast.from ? ast.from[0].table : null,
|
table: ast && ast.from ? ast.from[0].name : null,
|
||||||
tableAlias: ast && ast.from ? ast.from[0].as : null,
|
tableAlias: ast && ast.from ? ast.from[0].as : null,
|
||||||
orgTable: ast && ast.from ? ast.from[0].table : null,
|
orgTable: ast && ast.from ? ast.from[0].name : null,
|
||||||
type: this.types[field.dataTypeID]
|
type: this.types[field.dataTypeID] || field.format
|
||||||
};
|
};
|
||||||
}).filter(Boolean)
|
}).filter(Boolean)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
if (args.details) {
|
if (args.details) {
|
||||||
let cachedTable;
|
|
||||||
|
|
||||||
if (remappedFields.length) {
|
if (remappedFields.length) {
|
||||||
paramsArr = remappedFields.map(field => {
|
paramsArr = remappedFields.map(field => {
|
||||||
if (field.table) cachedTable = field.table;// Needed for some queries on information_schema
|
|
||||||
return {
|
return {
|
||||||
table: field.table || cachedTable,
|
table: field.table,
|
||||||
schema: field.schema || 'INFORMATION_SCHEMA'
|
schema: field.schema
|
||||||
};
|
};
|
||||||
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
|
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.key-mul,
|
&.key-mul,
|
||||||
&.key-INDEX {
|
&.key-INDEX,
|
||||||
|
&.key-KEY {
|
||||||
color: palegreen;
|
color: palegreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue