-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update searchVector at label identifier update for custom fields #7588
Changes from 7 commits
c0668c6
2b239cd
7531e4f
4abd180
6bb9aaa
524002d
f9f8f38
c9a8603
552ecee
ac4589a
a8650a1
a795da8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { TypeOrmModule } from '@nestjs/typeorm'; | ||
|
||
import { SimplifySearchVectorExpressionCommand } from 'src/database/commands/upgrade-version/0-31/0-32/0-32-simplify-search-vector-expression'; | ||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; | ||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; | ||
import { SearchModule } from 'src/engine/metadata-modules/search/search.module'; | ||
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; | ||
import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module'; | ||
|
||
@Module({ | ||
imports: [ | ||
TypeOrmModule.forFeature([Workspace], 'core'), | ||
TypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'), | ||
WorkspaceSyncMetadataCommandsModule, | ||
SearchModule, | ||
WorkspaceMigrationRunnerModule, | ||
], | ||
providers: [SimplifySearchVectorExpressionCommand], | ||
}) | ||
export class SimplifySearchVectorExpressionCommandModule {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
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 { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; | ||
import { | ||
FieldMetadataEntity, | ||
FieldMetadataType, | ||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; | ||
import { SearchService } from 'src/engine/metadata-modules/search/search.service'; | ||
import { SEARCH_FIELDS_FOR_CUSTOM_OBJECT } from 'src/engine/twenty-orm/custom.workspace-entity'; | ||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; | ||
import { | ||
COMPANY_STANDARD_FIELD_IDS, | ||
CUSTOM_OBJECT_STANDARD_FIELD_IDS, | ||
OPPORTUNITY_STANDARD_FIELD_IDS, | ||
PERSON_STANDARD_FIELD_IDS, | ||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||
import { FieldTypeAndNameMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util'; | ||
import { SEARCH_FIELDS_FOR_COMPANY } from 'src/modules/company/standard-objects/company.workspace-entity'; | ||
import { SEARCH_FIELDS_FOR_OPPORTUNITY } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; | ||
import { SEARCH_FIELDS_FOR_PERSON } from 'src/modules/person/standard-objects/person.workspace-entity'; | ||
|
||
@Command({ | ||
name: 'upgrade-0.32:simplify-search-vector-expression', | ||
description: 'Replace searchVector with simpler expression', | ||
}) | ||
export class SimplifySearchVectorExpressionCommand extends ActiveWorkspacesCommandRunner { | ||
constructor( | ||
@InjectRepository(Workspace, 'core') | ||
protected readonly workspaceRepository: Repository<Workspace>, | ||
@InjectRepository(FieldMetadataEntity, 'metadata') | ||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>, | ||
private readonly searchService: SearchService, | ||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService, | ||
) { | ||
super(workspaceRepository); | ||
} | ||
|
||
async executeActiveWorkspacesCommand( | ||
_passedParam: string[], | ||
_options: ActiveWorkspacesCommandOptions, | ||
workspaceIds: string[], | ||
): Promise<void> { | ||
this.logger.log('Running command to fix migration'); | ||
|
||
for (const workspaceId of workspaceIds) { | ||
this.logger.log(`Running command for workspace ${workspaceId}`); | ||
|
||
try { | ||
const searchVectorFields = await this.fieldMetadataRepository.findBy({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Weiko I could add some very specific logic here to filter out fields whose entry in _typeorm_generated_columns_and_materialized_views has a value containing "CASE" (it would imply declaring/creating the repository etc for this entity that we kind of decided to set aside so far). This would make the command idempotent, while it is not completely the case here - if we run the command multiple times the output will be the same but we will have re-created the column and index. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fine recreating everything as it will be executed only once. We can even go further and truncate the _typeorm_generated_columns_and_materialized_views table There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, as we just discussed I will do the truncate manually on the db so I can first test on a workspace independently. |
||
workspaceId: workspaceId, | ||
type: FieldMetadataType.TS_VECTOR, | ||
}); | ||
|
||
for (const searchVectorField of searchVectorFields) { | ||
let fieldsUsedForSearch: FieldTypeAndNameMetadata[] = []; | ||
|
||
switch (searchVectorField.standardId) { | ||
case CUSTOM_OBJECT_STANDARD_FIELD_IDS.searchVector: { | ||
fieldsUsedForSearch = SEARCH_FIELDS_FOR_CUSTOM_OBJECT; | ||
break; | ||
} | ||
case PERSON_STANDARD_FIELD_IDS.searchVector: { | ||
fieldsUsedForSearch = SEARCH_FIELDS_FOR_PERSON; | ||
break; | ||
} | ||
case COMPANY_STANDARD_FIELD_IDS.searchVector: { | ||
fieldsUsedForSearch = SEARCH_FIELDS_FOR_COMPANY; | ||
break; | ||
} | ||
case OPPORTUNITY_STANDARD_FIELD_IDS.searchVector: { | ||
fieldsUsedForSearch = SEARCH_FIELDS_FOR_OPPORTUNITY; | ||
break; | ||
} | ||
default: { | ||
throw new Error( | ||
`search vector has unexpected standardId: ${searchVectorField.standardId}`, | ||
); | ||
} | ||
} | ||
|
||
await this.searchService.updateSearchVector( | ||
searchVectorField.objectMetadataId, | ||
fieldsUsedForSearch, | ||
workspaceId, | ||
); | ||
|
||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations( | ||
workspaceId, | ||
); | ||
} | ||
} catch (error) { | ||
this.logger.log( | ||
chalk.red( | ||
`Running command on workspace ${workspaceId} failed with error: ${error}`, | ||
), | ||
); | ||
continue; | ||
} finally { | ||
this.logger.log( | ||
chalk.green(`Finished running command for workspace ${workspaceId}.`), | ||
); | ||
} | ||
|
||
this.logger.log(chalk.green(`Command completed!`)); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far I did not added this command to an upgrade-0.32 set of command as we would only want to run it twice and not to run it for self hosting