Use migrations for remote tables (#4877)

Foreign tables should be created using migrations, as we do for standard
tables.
Since those are not really generated from the object metadata but from
the remote table, those migrations won't live in the object metadata
service.

This PR:
- creates new types of migration : create_foreign_table and
drop_foreign_table
- triggers those migrations rather than raw queries directly
- moves the logic to fetch current foreign tables into the remote table
service since this is not directly linked to postgres data wrapper
- adds logic to unsync all tables before deleting

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette
2024-04-08 18:21:29 +02:00
committed by GitHub
parent d4a9a26069
commit 651af1c0e1
10 changed files with 241 additions and 112 deletions

View File

@ -18,6 +18,7 @@ import {
WorkspaceMigrationColumnCreateRelation,
WorkspaceMigrationColumnAlter,
WorkspaceMigrationColumnDropRelation,
WorkspaceMigrationForeignTable,
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service';
@ -131,6 +132,19 @@ export class WorkspaceMigrationRunnerService {
case 'drop':
await queryRunner.dropTable(`${schemaName}.${tableMigration.name}`);
break;
case 'create_foreign_table':
await this.createForeignTable(
queryRunner,
schemaName,
tableMigration.name,
tableMigration?.foreignTable,
);
break;
case 'drop_foreign_table':
await queryRunner.query(
`DROP FOREIGN TABLE ${schemaName}."${tableMigration.name}"`,
);
break;
default:
throw new Error(
`Migration table action ${tableMigration.action} not supported`,
@ -431,4 +445,27 @@ export class WorkspaceMigrationRunnerService {
COMMENT ON TABLE "${schemaName}"."${tableName}" IS e'${comment}';
`);
}
private async createForeignTable(
queryRunner: QueryRunner,
schemaName: string,
name: string,
foreignTable: WorkspaceMigrationForeignTable | undefined,
) {
if (!foreignTable) {
return;
}
const foreignTableColumns = foreignTable.columns
.map((column) => `"${column.columnName}" ${column.columnType}`)
.join(', ');
await queryRunner.query(
`CREATE FOREIGN TABLE ${schemaName}."${name}" (${foreignTableColumns}) SERVER "${foreignTable.foreignDataWrapperId}" OPTIONS (schema_name '${foreignTable.referencedTableSchema}', table_name '${foreignTable.referencedTableName}')`,
);
await queryRunner.query(`
COMMENT ON FOREIGN TABLE "${schemaName}"."${name}" IS '@graphql({"primary_key_columns": ["id"], "totalCount": {"enabled": true}})';
`);
}
}