Fix @directus/schema not reading Oracle overview correctly

Fixes #4735
This commit is contained in:
rijkvanzanten
2021-04-09 19:28:00 -04:00
parent a75c1ae8f4
commit c4e1e40279
3 changed files with 47 additions and 44 deletions

View File

@@ -7,7 +7,6 @@ const updates = [
{
column: 'group',
references: 'directus_fields.id',
onDelete: 'SET NULL',
},
],
},
@@ -17,17 +16,14 @@ const updates = [
{
column: 'folder',
references: 'directus_folders.id',
onDelete: 'SET NULL',
},
{
column: 'uploaded_by',
references: 'directus_users.id',
onDelete: 'SET NULL',
},
{
column: 'modified_by',
references: 'directus_users.id',
onDelete: 'SET NULL',
},
],
},
@@ -37,7 +33,6 @@ const updates = [
{
column: 'parent',
references: 'directus_folders.id',
onDelete: 'CASCADE',
},
],
},
@@ -47,7 +42,6 @@ const updates = [
{
column: 'role',
references: 'directus_roles.id',
onDelete: 'CASCADE',
},
],
},
@@ -57,12 +51,10 @@ const updates = [
{
column: 'user',
references: 'directus_users.id',
onDelete: 'CASCADE',
},
{
column: 'role',
references: 'directus_roles.id',
onDelete: 'CASCADE',
},
],
},
@@ -72,12 +64,10 @@ const updates = [
{
column: 'activity',
references: 'directus_activity.id',
onDelete: 'CASCADE',
},
{
column: 'parent',
references: 'directus_revisions.id',
onDelete: 'SET NULL',
},
],
},
@@ -87,7 +77,6 @@ const updates = [
{
column: 'user',
references: 'directus_users.id',
onDelete: 'CASCADE',
},
],
},
@@ -97,17 +86,14 @@ const updates = [
{
column: 'project_logo',
references: 'directus_files.id',
onDelete: 'SET NULL',
},
{
column: 'public_foreground',
references: 'directus_files.id',
onDelete: 'SET NULL',
},
{
column: 'public_background',
references: 'directus_files.id',
onDelete: 'SET NULL',
},
],
},
@@ -117,7 +103,6 @@ const updates = [
{
column: 'role',
references: 'directus_roles.id',
onDelete: 'SET NULL',
},
],
},
@@ -125,38 +110,26 @@ const updates = [
/**
* NOTE:
* MS SQL doesn't support recursive foreign key constraints, nor having multiple foreign key constraints to the same
* related table. This means that about half of the above constraint triggers won't be available in MS SQL. To avoid
* confusion in what's there and what isn't, we'll skip the on-delete / on-update triggers altogether in MS SQL.
* Not all databases allow (or support) recursive onUpdate/onDelete triggers. MS SQL / Oracle flat out deny creating them,
* Postgres behaves erratic on those triggers, not sure if MySQL / Maria plays nice either.
*/
export async function up(knex: Knex) {
if (knex.client.config.client === 'mssql') return;
for (const update of updates) {
await knex.schema.alterTable(update.table, (table) => {
for (const constraint of update.constraints) {
table.dropForeign([constraint.column]);
table
.foreign(constraint.column)
.references(constraint.references)
.onUpdate('CASCADE')
.onDelete(constraint.onDelete);
table.foreign(constraint.column).references(constraint.references);
}
});
}
}
export async function down(knex: Knex) {
if (knex.client.config.client === 'mssql') return;
for (const update of updates) {
await knex.schema.alterTable(update.table, (table) => {
for (const constraint of update.constraints) {
table.dropForeign([constraint.column]);
table.foreign(constraint.column).references(constraint.references).onUpdate('NO ACTION').onDelete('NO ACTION');
}
});
}

View File

@@ -43,7 +43,8 @@
"typescript": "^4.0.5"
},
"dependencies": {
"knex-schema-inspector": "^1.2.0"
"knex-schema-inspector": "^1.2.0",
"lodash": "^4.17.21"
},
"gitHead": "71bf628955b5da15ce3070dc09478bc558f243a4"
}

View File

@@ -1,19 +1,42 @@
import KnexOracle from 'knex-schema-inspector/dist/dialects/oracledb';
import { SchemaOverview } from '../types/overview';
import { SchemaInspector } from '../types/schema';
import { mapKeys } from 'lodash';
export default class Oracle extends KnexOracle implements SchemaInspector {
async overview() {
const columns = await this.knex.raw(`
type RawColumn = {
TABLE_NAME: string;
COLUMN_NAME: string;
DEFAULT_VALUE: string;
IS_NULLABLE: string;
DATA_TYPE: string;
NUMERIC_PRECISION: number | null;
NUMERIC_SCALE: number | null;
COLUMN_KEY: string;
};
type RawColumnLowercase = {
table_name: string;
column_name: string;
default_value: string;
is_nullable: string;
data_type: string;
numeric_precision: number | null;
numeric_scale: number | null;
column_key: string;
};
const columns = await this.knex.raw<RawColumn[]>(`
SELECT
"USER_TAB_COLUMNS"."TABLE_NAME" AS table_name,
"USER_TAB_COLUMNS"."COLUMN_NAME" AS column_name,
"USER_TAB_COLUMNS"."DATA_DEFAULT" AS default_value,
"USER_TAB_COLUMNS"."NULLABLE" AS is_nullable,
"USER_TAB_COLUMNS"."DATA_TYPE" AS data_type,
"USER_TAB_COLUMNS"."DATA_PRECISION" AS numeric_precision,
"USER_TAB_COLUMNS"."DATA_SCALE" AS numeric_scale,
"USER_CONSTRAINTS"."CONSTRAINT_TYPE" AS column_key
"USER_TAB_COLUMNS"."TABLE_NAME" AS TABLE_NAME,
"USER_TAB_COLUMNS"."COLUMN_NAME" AS COLUMN_NAME,
"USER_TAB_COLUMNS"."DATA_DEFAULT" AS DEFAULT_VALUE,
"USER_TAB_COLUMNS"."NULLABLE" AS IS_NULLABLE,
"USER_TAB_COLUMNS"."DATA_TYPE" AS DATA_TYPE,
"USER_TAB_COLUMNS"."DATA_PRECISION" AS NUMERIC_PRECISION,
"USER_TAB_COLUMNS"."DATA_SCALE" AS NUMERIC_SCALE,
"USER_CONSTRAINTS"."CONSTRAINT_TYPE" AS COLUMN_KEY
FROM
"USER_TAB_COLUMNS"
LEFT JOIN "USER_CONS_COLUMNS" ON "USER_TAB_COLUMNS"."TABLE_NAME" = "USER_CONS_COLUMNS"."TABLE_NAME"
@@ -21,14 +44,19 @@ export default class Oracle extends KnexOracle implements SchemaInspector {
LEFT JOIN "USER_CONSTRAINTS" ON "USER_CONS_COLUMNS"."CONSTRAINT_NAME" = "USER_CONSTRAINTS"."CONSTRAINT_NAME"
`);
const columnsLowercase: RawColumnLowercase[] = columns.map(
(column) => mapKeys(column, (value, key) => key.toLowerCase()) as RawColumnLowercase
);
const overview: SchemaOverview = {};
for (const column of columns[0]) {
for (const column of columnsLowercase) {
if (column.table_name in overview === false) {
overview[column.table_name] = {
primary: columns[0].find((nested: { column_key: string; table_name: string }) => {
return nested.table_name === column.table_name && nested.column_key === 'P';
})?.column_name,
primary:
columnsLowercase.find((nested: { column_key: string; table_name: string }) => {
return nested.table_name === column.table_name && nested.column_key === 'P';
})?.column_name || 'id',
columns: {},
};
}
@@ -38,6 +66,7 @@ export default class Oracle extends KnexOracle implements SchemaInspector {
is_nullable: column.is_nullable === 'YES',
};
}
return overview;
}
}