diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts new file mode 100644 index 0000000000..616ab04c58 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts @@ -0,0 +1,89 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { isNonEmptyString } from '@sniptt/guards'; +import { Command } from 'nest-commander'; +import { isDefined } from 'twenty-shared/utils'; +import { Repository } from 'typeorm'; + +import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; +import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; + +@Command({ + name: 'upgrade:1-21:backfill-datasource-to-workspace', + description: + 'Backfill workspace.databaseSchema from the dataSource entity for workspaces that have not been migrated yet', +}) +export class BackfillDatasourceToWorkspaceCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { + constructor( + @InjectRepository(WorkspaceEntity) + protected readonly workspaceRepository: Repository, + @InjectRepository(DataSourceEntity) + private readonly dataSourceRepository: Repository, + protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, + protected readonly dataSourceService: DataSourceService, + ) { + super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + } + + override async runOnWorkspace({ + workspaceId, + options, + }: RunOnWorkspaceArgs): Promise { + const isDryRun = options.dryRun ?? false; + + const workspace = await this.workspaceRepository.findOne({ + where: { id: workspaceId }, + }); + + if (!isDefined(workspace)) { + this.logger.warn(`Workspace ${workspaceId} not found, skipping`); + + return; + } + + if (isNonEmptyString(workspace.databaseSchema)) { + this.logger.log( + `Workspace ${workspaceId} already has databaseSchema="${workspace.databaseSchema}", skipping`, + ); + + return; + } + + const dataSource = await this.dataSourceRepository.findOne({ + where: { workspaceId }, + order: { createdAt: 'DESC' }, + }); + + if (!isDefined(dataSource)) { + throw new Error( + `No dataSource row found for workspace ${workspaceId}. Cannot backfill databaseSchema.`, + ); + } + + if (!isNonEmptyString(dataSource.schema)) { + throw new Error( + `DataSource for workspace ${workspaceId} has an empty schema. Cannot backfill databaseSchema.`, + ); + } + + if (isDryRun) { + this.logger.log( + `[DRY RUN] Would set workspace ${workspaceId} databaseSchema to "${dataSource.schema}"`, + ); + + return; + } + + await this.workspaceRepository.update(workspaceId, { + databaseSchema: dataSource.schema, + }); + + this.logger.log( + `Backfilled workspace ${workspaceId} databaseSchema to "${dataSource.schema}"`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts index 2de2445be8..9268fc7441 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts @@ -1,24 +1,32 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { BackfillDatasourceToWorkspaceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command'; import { BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; @Module({ imports: [ - TypeOrmModule.forFeature([WorkspaceEntity]), + TypeOrmModule.forFeature([WorkspaceEntity, DataSourceEntity]), DataSourceModule, WorkspaceCacheModule, ApplicationModule, WorkspaceMigrationModule, FeatureFlagModule, ], - providers: [BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand], - exports: [BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand], + providers: [ + BackfillDatasourceToWorkspaceCommand, + BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand, + ], + exports: [ + BackfillDatasourceToWorkspaceCommand, + BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand, + ], }) export class V1_21_UpgradeVersionCommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts index 8d0f3821f6..182f140220 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts @@ -12,6 +12,7 @@ import { import { CoreMigrationRunnerService } from 'src/database/commands/core-migration-runner/services/core-migration-runner.service'; import { BackfillCommandMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command'; import { BackfillNavigationMenuItemTypeCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command'; +import { BackfillDatasourceToWorkspaceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command'; import { BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command'; import { IdentifyFieldPermissionMetadataCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command'; import { BackfillSelectFieldOptionIdsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command'; @@ -68,6 +69,7 @@ export class UpgradeCommand extends UpgradeCommandRunner { protected readonly makeWorkflowSearchableCommand: MakeWorkflowSearchableCommand, // 1.21 Commands + protected readonly backfillDatasourceToWorkspaceCommand: BackfillDatasourceToWorkspaceCommand, protected readonly backfillPageLayoutsAndFieldsWidgetViewFieldsCommand: BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand, ) { super( @@ -102,6 +104,7 @@ export class UpgradeCommand extends UpgradeCommandRunner { ]; const commands_1210: VersionCommands = [ + this.backfillDatasourceToWorkspaceCommand, this.backfillPageLayoutsAndFieldsWidgetViewFieldsCommand, ];