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

@ -16,6 +16,8 @@ import {
validateString,
} from 'src/engine/metadata-modules/remote-server/utils/validate-remote-server-input';
import { ForeignDataWrapperQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/foreign-data-wrapper-query.factory';
import { RemoteTableService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.service';
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
@Injectable()
export class RemoteServerService<T extends RemoteServerType> {
@ -28,6 +30,7 @@ export class RemoteServerService<T extends RemoteServerType> {
private readonly metadataDataSource: DataSource,
private readonly environmentService: EnvironmentService,
private readonly foreignDataWrapperQueryFactory: ForeignDataWrapperQueryFactory,
private readonly remoteTableService: RemoteTableService,
) {}
async createOneRemoteServer(
@ -114,6 +117,26 @@ export class RemoteServerService<T extends RemoteServerType> {
throw new NotFoundException('Object does not exist');
}
const remoteTablesToRemove = (
await this.remoteTableService.findAvailableRemoteTablesByServerId(
id,
workspaceId,
)
).filter((remoteTable) => remoteTable.status === RemoteTableStatus.SYNCED);
if (remoteTablesToRemove.length) {
for (const remoteTable of remoteTablesToRemove) {
await this.remoteTableService.updateRemoteTableSyncStatus(
{
remoteServerId: id,
name: remoteTable.name,
status: RemoteTableStatus.NOT_SYNCED,
},
workspaceId,
);
}
}
return this.metadataDataSource.transaction(
async (entityManager: EntityManager) => {
await entityManager.query(