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 }) => {
try {
const query = connections[uid]
.select(`${column} AS foreignColumn`)
.select(`${column} AS foreign_column`)
.schema(schema)
.from(table)
.orderBy('foreignColumn ASC');
.orderBy('foreign_column ASC');
if (description)
query.select(`LEFT(${description}, 20) AS foreignDescription`);
query.select(`LEFT(${description}, 20) AS foreign_description`);
const results = await query.run();

View File

@ -352,12 +352,27 @@ export class PostgreSQLClient extends AntaresCore {
*/
async getKeyUsage ({ schema, table }) {
const { rows } = await this.raw(`
SELECT *
FROM information_schema.key_column_usage
JOIN information_schema.referential_constraints ON
referential_constraints.constraint_name = key_column_usage.constraint_name
WHERE table_schema = '${schema}'
AND table_name = '${table}'
SELECT
tc.table_schema,
tc.constraint_name,
tc.table_name,
kcu.column_name,
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 => {
@ -366,11 +381,11 @@ export class PostgreSQLClient extends AntaresCore {
table: field.table_name,
field: field.column_name,
position: field.ordinal_position,
constraintPosition: field.position_inUnique_constraint,
constraintPosition: field.position_in_unique_constraint,
constraintName: field.constraint_name,
refSchema: field.REFERENCED_TABLE_SCHEMA,
refTable: field.REFERENCED_TABLE_NAME,
refField: field.REFERENCED_COLUMN_NAME,
refSchema: field.foreign_table_schema,
refTable: field.foreign_table_name,
refField: field.foreign_column_name,
onUpdate: field.update_rule,
onDelete: field.delete_rule
};
@ -946,23 +961,6 @@ export class PostgreSQLClient extends AntaresCore {
arch: infos[1],
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 () {
@ -1261,9 +1259,11 @@ export class PostgreSQLClient extends AntaresCore {
const { rows, fields } = res;
let queryResult;
let tablesInfo;
if (args.nest) {
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 => {
return row.reduce((acc, curr, i) => {
@ -1281,12 +1281,21 @@ export class PostgreSQLClient extends AntaresCore {
if (!field || Array.isArray(field))
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 {
...field,
name: field.name,
alias: field.name,
schema: ast && ast.from && 'schema' in ast.from[0] ? ast.from[0].schema : this._schema,
table: ast && ast.from ? ast.from[0].name : null,
schema,
table,
// TODO: pick ast.from index if multiple
tableAlias: ast && ast.from ? ast.from[0].as : null,
orgTable: ast && ast.from ? ast.from[0].name : null,
type: this.types[field.dataTypeID] || field.format

View File

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

View File

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