Update searchVector on new richTextV2 note and task entities + migration command (#10303)
closes https://github.com/twentyhq/core-team-issues/issues/343 closes https://github.com/twentyhq/core-team-issues/issues/340
This commit is contained in:
@ -0,0 +1,117 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SearchService } from 'src/engine/metadata-modules/search/search.service';
|
||||
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
|
||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||
import { SEARCH_FIELDS_FOR_NOTES } from 'src/modules/note/standard-objects/note.workspace-entity';
|
||||
import { SEARCH_FIELDS_FOR_TASKS } from 'src/modules/task/standard-objects/task.workspace-entity';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.43:migrate-search-vector-on-note-and-task-entities',
|
||||
description: 'Migrate search vector on note and task entities',
|
||||
})
|
||||
export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveWorkspacesCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(FeatureFlag, 'core')
|
||||
protected readonly featureFlagRepository: Repository<FeatureFlag>,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
protected readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly searchService: SearchService,
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
|
||||
) {
|
||||
super(workspaceRepository);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
'Running command to migrate search vector on note and task entities',
|
||||
);
|
||||
|
||||
for (const [index, workspaceId] of workspaceIds.entries()) {
|
||||
await this.processWorkspace(workspaceId, index, workspaceIds.length);
|
||||
}
|
||||
|
||||
this.logger.log(chalk.green('Command completed!'));
|
||||
}
|
||||
|
||||
async processWorkspace(
|
||||
workspaceId: string,
|
||||
index: number,
|
||||
total: number,
|
||||
): Promise<void> {
|
||||
try {
|
||||
this.logger.log(
|
||||
`Running command for workspace ${workspaceId} ${index + 1}/${total}`,
|
||||
);
|
||||
|
||||
await this.featureFlagRepository.findOneOrFail({
|
||||
where: {
|
||||
workspaceId,
|
||||
key: FeatureFlagKey.IsRichTextV2Enabled,
|
||||
value: true,
|
||||
},
|
||||
});
|
||||
|
||||
const noteObjectMetadata =
|
||||
await this.objectMetadataRepository.findOneOrFail({
|
||||
select: ['id'],
|
||||
where: {
|
||||
workspaceId,
|
||||
nameSingular: 'note',
|
||||
},
|
||||
});
|
||||
|
||||
await this.searchService.updateSearchVector(
|
||||
noteObjectMetadata.id,
|
||||
SEARCH_FIELDS_FOR_NOTES,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const taskObjectMetadata =
|
||||
await this.objectMetadataRepository.findOneOrFail({
|
||||
select: ['id'],
|
||||
where: {
|
||||
workspaceId,
|
||||
nameSingular: 'task',
|
||||
},
|
||||
});
|
||||
|
||||
await this.searchService.updateSearchVector(
|
||||
taskObjectMetadata.id,
|
||||
SEARCH_FIELDS_FOR_TASKS,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.workspaceMetadataVersionService.incrementMetadataVersion(
|
||||
workspaceId,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.log(
|
||||
chalk.red(`Error in workspace ${workspaceId} - ${error.message}`),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,25 +2,33 @@ import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { AddTasksAssignedToMeViewCommand } from 'src/database/commands/upgrade-version/0-43/0-43-add-tasks-assigned-to-me-view.command';
|
||||
import { MigrateSearchVectorOnNoteAndTaskEntitiesCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command';
|
||||
import { UpgradeTo0_43Command } from 'src/database/commands/upgrade-version/0-43/0-43-upgrade-version.command';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SearchModule } from 'src/engine/metadata-modules/search/search.module';
|
||||
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace], 'core'),
|
||||
TypeOrmModule.forFeature([Workspace, FeatureFlag], 'core'),
|
||||
TypeOrmModule.forFeature(
|
||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
||||
'metadata',
|
||||
),
|
||||
SearchModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
],
|
||||
providers: [UpgradeTo0_43Command, AddTasksAssignedToMeViewCommand],
|
||||
providers: [
|
||||
UpgradeTo0_43Command,
|
||||
AddTasksAssignedToMeViewCommand,
|
||||
MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
|
||||
],
|
||||
})
|
||||
export class UpgradeTo0_43CommandModule {}
|
||||
|
||||
@ -31,9 +31,11 @@ import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/not
|
||||
import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity';
|
||||
|
||||
const TITLE_FIELD_NAME = 'title';
|
||||
const BODY_V2_FIELD_NAME = 'bodyV2';
|
||||
|
||||
export const SEARCH_FIELDS_FOR_NOTES: FieldTypeAndNameMetadata[] = [
|
||||
{ name: TITLE_FIELD_NAME, type: FieldMetadataType.TEXT },
|
||||
{ name: BODY_V2_FIELD_NAME, type: FieldMetadataType.RICH_TEXT_V2 },
|
||||
];
|
||||
|
||||
@WorkspaceEntity({
|
||||
|
||||
@ -34,8 +34,11 @@ import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/sta
|
||||
|
||||
const TITLE_FIELD_NAME = 'title';
|
||||
|
||||
export const SEARCH_FIELDS_FOR_TASK: FieldTypeAndNameMetadata[] = [
|
||||
const BODY_V2_FIELD_NAME = 'bodyV2';
|
||||
|
||||
export const SEARCH_FIELDS_FOR_TASKS: FieldTypeAndNameMetadata[] = [
|
||||
{ name: TITLE_FIELD_NAME, type: FieldMetadataType.TEXT },
|
||||
{ name: BODY_V2_FIELD_NAME, type: FieldMetadataType.RICH_TEXT_V2 },
|
||||
];
|
||||
|
||||
@WorkspaceEntity({
|
||||
@ -205,7 +208,9 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity {
|
||||
description: SEARCH_VECTOR_FIELD.description,
|
||||
icon: 'IconUser',
|
||||
generatedType: 'STORED',
|
||||
asExpression: getTsVectorColumnExpressionFromFields(SEARCH_FIELDS_FOR_TASK),
|
||||
asExpression: getTsVectorColumnExpressionFromFields(
|
||||
SEARCH_FIELDS_FOR_TASKS,
|
||||
),
|
||||
})
|
||||
@WorkspaceIsNullable()
|
||||
@WorkspaceIsSystem()
|
||||
|
||||
Reference in New Issue
Block a user