Deprecate dataSource table with dual-write to workspace.databaseSchema (#19059)
## Summary - Starts deprecation of the `core.dataSource` table by introducing a dual-write system: `DataSourceService.createDataSourceMetadata` now writes to both `core.dataSource` and `core.workspace.databaseSchema` - Migrates read sites (`WorkspaceDataSourceService.checkSchemaExists`, `WorkspaceSchemaFactory`, `MiddlewareService`, `WorkspacesMigrationCommandRunner`) to read from `workspace.databaseSchema` instead of querying the `dataSource` table - Removes the unused `databaseUrl` field from `WorkspaceEntity` and drops the column via migration - Adds a 1.20 upgrade command to backfill `workspace.databaseSchema` from `dataSource.schema` for existing workspaces
This commit is contained in:
@@ -14,6 +14,9 @@ import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/works
|
||||
|
||||
export type DataSourceType = DataSourceOptions['type'];
|
||||
|
||||
// @deprecated - This entity is being deprecated in favor of storing
|
||||
// databaseSchema directly on WorkspaceEntity.
|
||||
// During the transition, writes go to both tables (dual-write).
|
||||
@Entity('dataSource')
|
||||
@Index('IDX_DATA_SOURCE_WORKSPACE_ID_CREATED_AT', ['workspaceId', 'createdAt'])
|
||||
export class DataSourceEntity extends WorkspaceRelatedEntity {
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
import { DataSourceEntity } from './data-source.entity';
|
||||
import { DataSourceService } from './data-source.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([DataSourceEntity])],
|
||||
imports: [TypeOrmModule.forFeature([DataSourceEntity, WorkspaceEntity])],
|
||||
providers: [DataSourceService],
|
||||
exports: [DataSourceService],
|
||||
})
|
||||
|
||||
+25
-1
@@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { type FindManyOptions, Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import {
|
||||
DataSourceException,
|
||||
DataSourceExceptionCode,
|
||||
@@ -10,22 +11,32 @@ import {
|
||||
|
||||
import { DataSourceEntity } from './data-source.entity';
|
||||
|
||||
// @deprecated - This service is being deprecated. During the transition,
|
||||
// writes go to both the dataSource table and workspace table (dual-write).
|
||||
// Reads should progressively migrate to use workspace.databaseSchema
|
||||
// or the deterministic getWorkspaceSchemaName(workspaceId) utility.
|
||||
@Injectable()
|
||||
export class DataSourceService {
|
||||
constructor(
|
||||
@InjectRepository(DataSourceEntity)
|
||||
private readonly dataSourceMetadataRepository: Repository<DataSourceEntity>,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
) {}
|
||||
|
||||
async createDataSourceMetadata(
|
||||
workspaceId: string,
|
||||
workspaceSchema: string,
|
||||
): Promise<DataSourceEntity> {
|
||||
// TODO: Double check if this is the correct way to do this
|
||||
const dataSource = await this.dataSourceMetadataRepository.findOne({
|
||||
where: { workspaceId },
|
||||
});
|
||||
|
||||
// Dual-write: always keep workspace.databaseSchema in sync
|
||||
await this.workspaceRepository.update(workspaceId, {
|
||||
databaseSchema: workspaceSchema,
|
||||
});
|
||||
|
||||
if (dataSource) {
|
||||
return dataSource;
|
||||
}
|
||||
@@ -36,12 +47,16 @@ export class DataSourceService {
|
||||
});
|
||||
}
|
||||
|
||||
// @deprecated - Use workspace.activationStatus or workspace.databaseSchema
|
||||
// to check if a workspace has been initialized instead.
|
||||
async getManyDataSourceMetadata(
|
||||
options: FindManyOptions<DataSourceEntity> = {},
|
||||
): Promise<DataSourceEntity[]> {
|
||||
return this.dataSourceMetadataRepository.find(options);
|
||||
}
|
||||
|
||||
// @deprecated - Use workspace.databaseSchema or
|
||||
// getWorkspaceSchemaName(workspaceId) instead.
|
||||
async getDataSourcesMetadataFromWorkspaceId(
|
||||
workspaceId: string,
|
||||
): Promise<DataSourceEntity[]> {
|
||||
@@ -51,6 +66,8 @@ export class DataSourceService {
|
||||
});
|
||||
}
|
||||
|
||||
// @deprecated - Use workspace.databaseSchema or
|
||||
// getWorkspaceSchemaName(workspaceId) instead.
|
||||
async getLastDataSourceMetadataFromWorkspaceId(
|
||||
workspaceId: string,
|
||||
): Promise<DataSourceEntity | null> {
|
||||
@@ -60,6 +77,8 @@ export class DataSourceService {
|
||||
});
|
||||
}
|
||||
|
||||
// @deprecated - Use workspace.databaseSchema or
|
||||
// getWorkspaceSchemaName(workspaceId) instead.
|
||||
async getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
workspaceId: string,
|
||||
): Promise<DataSourceEntity> {
|
||||
@@ -78,5 +97,10 @@ export class DataSourceService {
|
||||
|
||||
async delete(workspaceId: string): Promise<void> {
|
||||
await this.dataSourceMetadataRepository.delete({ workspaceId });
|
||||
|
||||
// Dual-write: clear workspace.databaseSchema on delete
|
||||
await this.workspaceRepository.update(workspaceId, {
|
||||
databaseSchema: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user