-
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
Add unique indexes and indexes for composite types #7162
Conversation
Todo:
|
variant: SnackBarVariant.Error, | ||
}, | ||
); | ||
enqueueSnackBar(`${error.message}`, { |
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.
was too dev-oriented
variant: SnackBarVariant.Error, | ||
}, | ||
); | ||
enqueueSnackBar(`Error finding duplicates:", ${error.message}`, { |
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.
was too dev-oriented
@@ -20,7 +20,7 @@ export const PromiseRejectionEffect = () => { | |||
}, | |||
); | |||
} else { | |||
enqueueSnackBar(`Error: ${event.reason}`, { | |||
enqueueSnackBar(`${error.message}`, { |
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.
red color and message usually already convey the fact that it's an error, and there's limited space
@@ -0,0 +1,53 @@ | |||
import { MigrationInterface, QueryRunner } from 'typeorm'; | |||
|
|||
export class MigrationDebt1726757368824 implements MigrationInterface { |
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.
This is not directly related to this PR but it reflects that migrations <> typeorm entities were out of sync. I ran this a few weeks ago when opening the PR but it seems the debt hasn't been picked up by anyone since
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.
Thanks! Ideally we should enforce a rule (danger?)
If *.entity.ts files are updated, a migration should be generated 🤔
.../src/database/typeorm/metadata/migrations/1726762935841-addColumnNameToIndexFieldMetadata.ts
Outdated
Show resolved
Hide resolved
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||
|
||
@Command({ | ||
name: 'upgrade-0.31:enforce-unique-constraints', |
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.
This isn't ready to be reviewed yet
8a743f6
to
d125250
Compare
@@ -0,0 +1,53 @@ | |||
import { MigrationInterface, QueryRunner } from 'typeorm'; | |||
|
|||
export class MigrationDebt1726757368824 implements MigrationInterface { |
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.
Thanks! Ideally we should enforce a rule (danger?)
If *.entity.ts files are updated, a migration should be generated 🤔
...atabase/typeorm/metadata/migrations/1726762935841-addCompostiveColumnToIndexFieldMetadata.ts
Outdated
Show resolved
Hide resolved
...ql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts
Outdated
Show resolved
Hide resolved
packages/twenty-server/src/engine/twenty-orm/decorators/workspace-column-index.decorator.ts
Outdated
Show resolved
Hide resolved
import { WorkspaceActivationStatus } from '~/generated/graphql'; | ||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems'; | ||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; | ||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; | ||
|
||
const filterTsVectorFields = ( |
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.
I think we want to keep that?
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.
Oh I see it seems you handled it differently 👍
@@ -40,7 +40,7 @@ export class CreateManyResolverFactory | |||
|
|||
return await this.graphqlQueryRunnerService.createMany(args, options); | |||
} catch (error) { | |||
workspaceQueryRunnerGraphqlApiExceptionHandler(error); | |||
workspaceQueryRunnerGraphqlApiExceptionHandler(error, context); |
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.
should we use internalContext here as well to keep it consistent and avoid issues with _context?
@@ -114,6 +115,7 @@ export class TypeMapperService { | |||
[FieldMetadataType.RAW_JSON, RawJsonFilterType], | |||
[FieldMetadataType.RICH_TEXT, StringFilterType], | |||
[FieldMetadataType.ARRAY, ArrayFilterType], | |||
[FieldMetadataType.TS_VECTOR, StringFilterType], |
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.
I'm not sure we want that already. TS_VECTOR is dedicated to searchVector field and search is only applied in the search resolver (which does not contain filter). We might want to combine filters later on but I'm not sure this change is needed? This won't be properly reflected in the API at least, your filter won't work as expected with a StringFilter on a tsvector column
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.
PR Summary
This pull request adds support for unique indexes and indexes on composite fields, focusing on enhancing data integrity and query performance. Key changes include:
- Added
indexMetadatas
field toObjectMetadataItem
type, supporting index information retrieval - Introduced new types
IndexMetadataItem
andIndexFieldMetadataItem
for handling index-related data - Updated GraphQL queries and schemas to include index metadata and uniqueness constraints
- Modified database migrations to add
isUnique
andindexWhereClause
fields to index metadata - Enhanced error handling in GraphQL resolvers for unique constraint violations
- Removed filtering of TsVector fields in
ObjectMetadataItemsLoadEffect
, potentially exposing them in the UI
30 file(s) reviewed, 10 comment(s)
Edit PR Review Bot Settings | Greptile
import { useQuery } from '@apollo/client'; | ||
import { useMemo } from 'react'; |
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.
style: Import order changed. Consider using a consistent import order throughout the codebase.
indexType: z.nativeEnum(IndexType), | ||
indexWhereClause: z.string().nullable(), | ||
isUnique: z.boolean(), | ||
objectMetadata: z.any(), |
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.
style: objectMetadata: z.any() is too permissive. Define a more specific schema
enqueueSnackBar(`Error finding duplicates:", ${error.message}`, { | ||
variant: SnackBarVariant.Error, | ||
}); |
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.
style: Error message simplified, but consider including the object name for context
enqueueSnackBar(`${error.message}`, { | ||
variant: SnackBarVariant.Error, | ||
}); |
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.
style: Consider adding a generic prefix to error messages for consistency
if (isFieldTsVector(fieldDefinition)) { | ||
return false; | ||
} |
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.
logic: TsVector fields are always considered non-empty. Ensure this behavior is intended and doesn't cause unexpected side effects in other parts of the application.
throw new Error( | ||
`Entity field type not supported in isFieldValueEmpty : ${fieldDefinition.type}}`, | ||
); |
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.
style: Consider using a more specific error type or including the field type in the error message for easier debugging.
packages/twenty-front/src/modules/ui/field/display/components/EllipsisDisplay.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/ui/field/display/components/EllipsisDisplay.tsx
Outdated
Show resolved
Hide resolved
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.
Big one! Let's iterate from there!
Add support for indexes on composite fields and unicity constraint on indexes
This pull request includes several changes across multiple files to improve error handling, enforce unique constraints, and update database migrations. The most important changes include updating error messages for snack bars, adding a new command to enforce unique constraints, and updating database migrations to include new fields and constraints.
Error Handling Improvements:
packages/twenty-front/src/modules/error-handler/components/PromiseRejectionEffect.tsx
: Updated error messages inenqueueSnackBar
to useerror.message
directly.packages/twenty-front/src/modules/object-metadata/hooks/useFindManyObjectMetadataItems.ts
: Simplified error messages inenqueueSnackBar
.packages/twenty-front/src/modules/object-record/hooks/useFindDuplicateRecords.ts
: Simplified error messages inenqueueSnackBar
.packages/twenty-front/src/modules/object-record/hooks/useHandleFindManyRecordsError.ts
: Simplified error messages inenqueueSnackBar
.New Command for Unique Constraints:
packages/twenty-server/src/database/commands/upgrade-version/0-31/0-31-enforce-unique-constraints.command.ts
: Added a new command to enforce unique constraints on company domain names and person emails.packages/twenty-server/src/database/commands/upgrade-version/0-31/0-31-upgrade-version.command.ts
: Integrated the newEnforceUniqueConstraintsCommand
into the upgrade process. [1] [2] [3]packages/twenty-server/src/database/commands/upgrade-version/0-31/0-31-upgrade-version.module.ts
: Registered the newEnforceUniqueConstraintsCommand
in the module. [1] [2]Database Migrations:
packages/twenty-server/src/database/typeorm/metadata/migrations/1726757368824-migrationDebt.ts
: Added a migration to update therelationMetadata_ondeleteaction_enum
and set default values.packages/twenty-server/src/database/typeorm/metadata/migrations/1726757368825-addIsUniqueToIndexMetadata.ts
: Added a migration to include theisUnique
field inindexMetadata
.packages/twenty-server/src/database/typeorm/metadata/migrations/1726762935841-addCompostiveColumnToIndexFieldMetadata.ts
: Added a migration to include thecompositeColumn
field inindexFieldMetadata
.packages/twenty-server/src/database/typeorm/metadata/migrations/1726766871572-addWhereToIndexMetadata.ts
: Added a migration to include theindexWhereClause
field inindexMetadata
.GraphQL Exception Handling:
packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts
: Enhanced exception handling forQueryFailedError
to provide more specific error messages for unique constraint violations. [1] [2]packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts
: Updated theworkspaceQueryRunnerGraphqlApiExceptionHandler
call to include context.packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts
: Updated theworkspaceQueryRunnerGraphqlApiExceptionHandler
call to include context.