fix(PostgreSQL): issue getting foreign keys informations

This commit is contained in:
Fabio Di Stasio 2021-03-21 11:51:22 +01:00
parent e89911b185
commit db47b4040a
4 changed files with 56 additions and 45 deletions

View File

@ -378,13 +378,13 @@ export default (connections) => {
ipcMain.handle('get-foreign-list', async (event, { uid, schema, table, column, description }) => { ipcMain.handle('get-foreign-list', async (event, { uid, schema, table, column, description }) => {
try { try {
const query = connections[uid] const query = connections[uid]
.select(`${column} AS foreignColumn`) .select(`${column} AS foreign_column`)
.schema(schema) .schema(schema)
.from(table) .from(table)
.orderBy('foreignColumn ASC'); .orderBy('foreign_column ASC');
if (description) if (description)
query.select(`LEFT(${description}, 20) AS foreignDescription`); query.select(`LEFT(${description}, 20) AS foreign_description`);
const results = await query.run(); const results = await query.run();

View File

@ -352,12 +352,27 @@ export class PostgreSQLClient extends AntaresCore {
*/ */
async getKeyUsage ({ schema, table }) { async getKeyUsage ({ schema, table }) {
const { rows } = await this.raw(` const { rows } = await this.raw(`
SELECT * SELECT
FROM information_schema.key_column_usage tc.table_schema,
JOIN information_schema.referential_constraints ON tc.constraint_name,
referential_constraints.constraint_name = key_column_usage.constraint_name tc.table_name,
WHERE table_schema = '${schema}' kcu.column_name,
AND table_name = '${table}' ccu.table_schema AS foreign_table_schema,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name,
rc.update_rule,
rc.delete_rule
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
AND ccu.table_schema = tc.table_schema
JOIN information_schema.referential_constraints AS rc
ON rc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = '${schema}'
AND tc.table_name = '${table}'
`); `);
return rows.map(field => { return rows.map(field => {
@ -366,11 +381,11 @@ export class PostgreSQLClient extends AntaresCore {
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_inUnique_constraint, constraintPosition: field.position_in_unique_constraint,
constraintName: field.constraint_name, constraintName: field.constraint_name,
refSchema: field.REFERENCED_TABLE_SCHEMA, refSchema: field.foreign_table_schema,
refTable: field.REFERENCED_TABLE_NAME, refTable: field.foreign_table_name,
refField: field.REFERENCED_COLUMN_NAME, refField: field.foreign_column_name,
onUpdate: field.update_rule, onUpdate: field.update_rule,
onDelete: field.delete_rule onDelete: field.delete_rule
}; };
@ -946,23 +961,6 @@ export class PostgreSQLClient extends AntaresCore {
arch: infos[1], arch: infos[1],
os: infos[2] os: infos[2]
}; };
// return rows.reduce((acc, curr) => {
// switch (curr.Variable_name) {
// case 'version':
// acc.number = curr.Value.split('-')[0];
// break;
// case 'version_comment':
// acc.name = curr.Value.replace('(GPL)', '');
// break;
// case 'version_compile_machine':
// acc.arch = curr.Value;
// break;
// case 'version_compile_os':
// acc.os = curr.Value;
// break;
// }
// return acc;
// }, {});
} }
async getProcesses () { async getProcesses () {
@ -1261,9 +1259,11 @@ export class PostgreSQLClient extends AntaresCore {
const { rows, fields } = res; const { rows, fields } = res;
let queryResult; let queryResult;
let tablesInfo;
if (args.nest) { if (args.nest) {
const tablesID = [...new Set(fields.map(field => field.tableID))].toString(); const tablesID = [...new Set(fields.map(field => field.tableID))].toString();
const tablesInfo = await this.getTableByIDs(tablesID); tablesInfo = await this.getTableByIDs(tablesID);
queryResult = rows.map(row => { queryResult = rows.map(row => {
return row.reduce((acc, curr, i) => { return row.reduce((acc, curr, i) => {
@ -1281,12 +1281,21 @@ export class PostgreSQLClient extends AntaresCore {
if (!field || Array.isArray(field)) if (!field || Array.isArray(field))
return false; return false;
let schema = ast && ast.from && 'schema' in ast.from[0] ? ast.from[0].schema : this._schema;
let table = ast && ast.from ? ast.from[0].name : null;
if (args.nest) {
schema = tablesInfo[field.tableID] ? tablesInfo[field.tableID].schema : this._schema;
table = tablesInfo[field.tableID] ? tablesInfo[field.tableID].table : null;
}
return { return {
...field, ...field,
name: field.name, name: field.name,
alias: field.name, alias: field.name,
schema: ast && ast.from && 'schema' in ast.from[0] ? ast.from[0].schema : this._schema, schema,
table: ast && ast.from ? ast.from[0].name : null, table,
// TODO: pick ast.from index if multiple
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].name : null, orgTable: ast && ast.from ? ast.from[0].name : null,
type: this.types[field.dataTypeID] || field.format type: this.types[field.dataTypeID] || field.format

View File

@ -11,11 +11,11 @@
</option> </option>
<option <option
v-for="row in foreignList" v-for="row in foreignList"
:key="row.foreignColumn" :key="row.foreign_column"
:value="row.foreignColumn" :value="row.foreign_column"
:selected="row.foreignColumn === value" :selected="row.foreign_column === value"
> >
{{ row.foreignColumn }} {{ 'foreignDescription' in row ? ` - ${row.foreignDescription}` : '' | cutText }} {{ row.foreign_column }} {{ 'foreign_description' in row ? ` - ${row.foreign_description}` : '' | cutText }}
</option> </option>
</select> </select>
</template> </template>
@ -51,11 +51,11 @@ export default {
}), }),
isValidDefault () { isValidDefault () {
if (!this.foreignList.length) return true; if (!this.foreignList.length) return true;
return this.foreignList.some(foreign => foreign.foreignColumn.toString() === this.value.toString()); return this.foreignList.some(foreign => foreign.foreign_column.toString() === this.value.toString());
} }
}, },
async created () { async created () {
let firstTextField; let foreignDesc;
const params = { const params = {
uid: this.selectedWorkspace, uid: this.selectedWorkspace,
schema: this.keyUsage.refSchema, schema: this.keyUsage.refSchema,
@ -64,8 +64,10 @@ export default {
try { // Field data try { // Field data
const { status, response } = await Tables.getTableColumns(params); const { status, response } = await Tables.getTableColumns(params);
if (status === 'success') if (status === 'success') {
firstTextField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type)).name || false; const textField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type));
foreignDesc = textField ? textField.name : false;
}
else else
this.addNotification({ status: 'error', message: response }); this.addNotification({ status: 'error', message: response });
} }
@ -77,7 +79,7 @@ export default {
const { status, response } = await Tables.getForeignList({ const { status, response } = await Tables.getForeignList({
...params, ...params,
column: this.keyUsage.refField, column: this.keyUsage.refField,
description: firstTextField description: foreignDesc
}); });
if (status === 'success') if (status === 'success')

View File

@ -1,4 +1,4 @@
@import "~spectre.css/src/variables"; @import "~spectre.css/src/_variables.scss";
@import "variables"; @import "variables";
@import "transitions"; @import "transitions";
@import "data-types"; @import "data-types";
@ -6,8 +6,8 @@
@import "fake-tables"; @import "fake-tables";
@import "mdi-additions"; @import "mdi-additions";
@import "db-icons"; @import "db-icons";
@import "~spectre.css/src/spectre"; @import "~spectre.css/src/spectre.scss";
@import "~spectre.css/src/spectre-exp"; @import "~spectre.css/src/spectre-exp.scss";
body { body {
user-select: none; user-select: none;