Fallback to default value when migrating value from enum (#6517)
When migrating the option values of a select type, if the field is non nullable (for now, only available for opportunity's "stage" standard field), we fallback to the (potentially updated) default value instead of nullifying the value to avoid getting a database error. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -100,6 +100,11 @@ export type FieldRichTextMetadata = {
|
|||||||
fieldName: string;
|
fieldName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FieldPositionMetadata = {
|
||||||
|
objectMetadataNameSingular?: string;
|
||||||
|
fieldName: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type FieldDefinitionRelationType =
|
export type FieldDefinitionRelationType =
|
||||||
| 'FROM_MANY_OBJECTS'
|
| 'FROM_MANY_OBJECTS'
|
||||||
| 'FROM_ONE_OBJECT'
|
| 'FROM_ONE_OBJECT'
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
|
import { FieldDefinition } from '../FieldDefinition';
|
||||||
|
import { FieldMetadata, FieldPositionMetadata } from '../FieldMetadata';
|
||||||
|
|
||||||
|
export const isFieldPosition = (
|
||||||
|
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||||
|
): field is FieldDefinition<FieldPositionMetadata> =>
|
||||||
|
field.type === FieldMetadataType.Position;
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { isNumber } from '@sniptt/guards';
|
||||||
|
import { FieldPositionMetadata } from '../FieldMetadata';
|
||||||
|
|
||||||
|
// TODO: add zod
|
||||||
|
export const isFieldPhoneValue = (
|
||||||
|
fieldValue: unknown,
|
||||||
|
): fieldValue is FieldPositionMetadata =>
|
||||||
|
isNumber(fieldValue) || fieldValue === 'first' || fieldValue === 'last';
|
||||||
@ -22,6 +22,7 @@ import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/is
|
|||||||
import { isFieldMultiSelectValue } from '@/object-record/record-field/types/guards/isFieldMultiSelectValue';
|
import { isFieldMultiSelectValue } from '@/object-record/record-field/types/guards/isFieldMultiSelectValue';
|
||||||
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
||||||
import { isFieldPhone } from '@/object-record/record-field/types/guards/isFieldPhone';
|
import { isFieldPhone } from '@/object-record/record-field/types/guards/isFieldPhone';
|
||||||
|
import { isFieldPosition } from '@/object-record/record-field/types/guards/isFieldPosition';
|
||||||
import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating';
|
import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating';
|
||||||
import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson';
|
import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson';
|
||||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||||
@ -58,7 +59,8 @@ export const isFieldValueEmpty = ({
|
|||||||
isFieldRelation(fieldDefinition) ||
|
isFieldRelation(fieldDefinition) ||
|
||||||
isFieldRawJson(fieldDefinition) ||
|
isFieldRawJson(fieldDefinition) ||
|
||||||
isFieldRichText(fieldDefinition) ||
|
isFieldRichText(fieldDefinition) ||
|
||||||
isFieldPhone(fieldDefinition)
|
isFieldPhone(fieldDefinition) ||
|
||||||
|
isFieldPosition(fieldDefinition)
|
||||||
) {
|
) {
|
||||||
return isValueEmpty(fieldValue);
|
return isValueEmpty(fieldValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export const getCurrencyFieldPreviewValue = ({
|
|||||||
|
|
||||||
const placeholderDefaultValue = getSettingsFieldTypeConfig(
|
const placeholderDefaultValue = getSettingsFieldTypeConfig(
|
||||||
FieldMetadataType.Currency,
|
FieldMetadataType.Currency,
|
||||||
).defaultValue;
|
).exampleValue;
|
||||||
|
|
||||||
return currencyFieldDefaultValueSchema
|
return currencyFieldDefaultValueSchema
|
||||||
.transform((value) => ({
|
.transform((value) => ({
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
import { FieldMetadataDefaultSerializableValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface';
|
||||||
|
|
||||||
|
export const unserializeDefaultValue = (
|
||||||
|
serializedDefaultValue: FieldMetadataDefaultSerializableValue,
|
||||||
|
): any => {
|
||||||
|
if (serializedDefaultValue === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof serializedDefaultValue === 'number') {
|
||||||
|
return serializedDefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof serializedDefaultValue === 'boolean') {
|
||||||
|
return serializedDefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof serializedDefaultValue === 'string') {
|
||||||
|
return serializedDefaultValue.replace(/'/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(serializedDefaultValue)) {
|
||||||
|
return serializedDefaultValue.map((value) =>
|
||||||
|
unserializeDefaultValue(value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof serializedDefaultValue === 'object') {
|
||||||
|
return Object.entries(serializedDefaultValue).reduce(
|
||||||
|
(acc, [key, value]) => {
|
||||||
|
acc[key] = unserializeDefaultValue(value);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
`Invalid serialized default value "${serializedDefaultValue}"`,
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -34,6 +34,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -64,6 +65,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -94,6 +96,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -124,6 +127,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -154,6 +158,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -184,6 +189,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -211,6 +217,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
columnName: 'position',
|
columnName: 'position',
|
||||||
columnType: 'float',
|
columnType: 'float',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
@ -224,6 +231,7 @@ export const buildMigrationsForCustomObjectRelations = (
|
|||||||
columnName: 'name',
|
columnName: 'name',
|
||||||
columnType: 'text',
|
columnType: 'text',
|
||||||
defaultValue: "'Untitled'",
|
defaultValue: "'Untitled'",
|
||||||
|
isNullable: false,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
|||||||
@ -2,36 +2,36 @@ import { Injectable, NotFoundException } from '@nestjs/common';
|
|||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||||
import { FindOneOptions, In, Repository } from 'typeorm';
|
|
||||||
import camelCase from 'lodash.camelcase';
|
import camelCase from 'lodash.camelcase';
|
||||||
|
import { FindOneOptions, In, Repository } from 'typeorm';
|
||||||
import { v4 as uuidV4 } from 'uuid';
|
import { v4 as uuidV4 } from 'uuid';
|
||||||
|
|
||||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
|
||||||
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
|
|
||||||
import { CreateRelationInput } from 'src/engine/metadata-modules/relation-metadata/dtos/create-relation.input';
|
|
||||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
|
||||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
|
||||||
import {
|
import {
|
||||||
FieldMetadataEntity,
|
FieldMetadataEntity,
|
||||||
FieldMetadataType,
|
FieldMetadataType,
|
||||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
|
||||||
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||||
|
import { CreateRelationInput } from 'src/engine/metadata-modules/relation-metadata/dtos/create-relation.input';
|
||||||
|
import {
|
||||||
|
RelationMetadataException,
|
||||||
|
RelationMetadataExceptionCode,
|
||||||
|
} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.exception';
|
||||||
|
import {
|
||||||
|
InvalidStringException,
|
||||||
|
validateMetadataNameOrThrow,
|
||||||
|
} from 'src/engine/metadata-modules/utils/validate-metadata-name.utils';
|
||||||
|
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||||
|
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
WorkspaceMigrationColumnDrop,
|
WorkspaceMigrationColumnDrop,
|
||||||
WorkspaceMigrationTableActionType,
|
WorkspaceMigrationTableActionType,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||||
import {
|
|
||||||
validateMetadataNameOrThrow,
|
|
||||||
InvalidStringException,
|
|
||||||
} from 'src/engine/metadata-modules/utils/validate-metadata-name.utils';
|
|
||||||
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
|
||||||
import {
|
|
||||||
RelationMetadataException,
|
|
||||||
RelationMetadataExceptionCode,
|
|
||||||
} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.exception';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
RelationMetadataEntity,
|
RelationMetadataEntity,
|
||||||
@ -213,6 +213,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
|||||||
columnName,
|
columnName,
|
||||||
columnType: 'uuid',
|
columnType: 'uuid',
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -15,10 +15,10 @@ import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/worksp
|
|||||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||||
import {
|
import {
|
||||||
ReferencedTable,
|
ReferencedTable,
|
||||||
WorkspaceMigrationTableActionType,
|
WorkspaceMigrationColumnAction,
|
||||||
WorkspaceMigrationForeignColumnDefinition,
|
WorkspaceMigrationForeignColumnDefinition,
|
||||||
WorkspaceMigrationForeignTable,
|
WorkspaceMigrationForeignTable,
|
||||||
WorkspaceMigrationColumnAction,
|
WorkspaceMigrationTableActionType,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
@ -77,6 +77,8 @@ export class ForeignTableService {
|
|||||||
columnName: getForeignTableColumnName(column.columnName),
|
columnName: getForeignTableColumnName(column.columnName),
|
||||||
columnType: column.dataType,
|
columnType: column.dataType,
|
||||||
distantColumnName: column.columnName,
|
distantColumnName: column.columnName,
|
||||||
|
isNullable: false,
|
||||||
|
defaultValue: null,
|
||||||
}) satisfies WorkspaceMigrationForeignColumnDefinition,
|
}) satisfies WorkspaceMigrationForeignColumnDefinition,
|
||||||
),
|
),
|
||||||
referencedTable,
|
referencedTable,
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationTableAction,
|
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
WorkspaceMigrationColumnCreate,
|
WorkspaceMigrationColumnCreate,
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
WorkspaceMigrationTableActionType,
|
WorkspaceMigrationTableActionType,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
@ -24,6 +24,7 @@ export const buildMigrationsToCreateRemoteTableRelations = (
|
|||||||
}),
|
}),
|
||||||
columnType: primaryKeyColumnType,
|
columnType: primaryKeyColumnType,
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { getForeignTableColumnName as convertToForeignTableColumnName } from 'src/engine/metadata-modules/remote-server/remote-table/foreign-table/utils/get-foreign-table-column-name.util';
|
|
||||||
import { DistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/types/distant-table';
|
import { DistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/types/distant-table';
|
||||||
import { DistantTableUpdate } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
|
import { DistantTableUpdate } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
|
||||||
|
import { getForeignTableColumnName as convertToForeignTableColumnName } from 'src/engine/metadata-modules/remote-server/remote-table/foreign-table/utils/get-foreign-table-column-name.util';
|
||||||
import { RemoteTableEntity } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.entity';
|
import { RemoteTableEntity } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.entity';
|
||||||
import { fetchTableColumns } from 'src/engine/metadata-modules/remote-server/remote-table/utils/fetch-table-columns.util';
|
import { fetchTableColumns } from 'src/engine/metadata-modules/remote-server/remote-table/utils/fetch-table-columns.util';
|
||||||
import { PostgresTableSchemaColumn } from 'src/engine/metadata-modules/remote-server/types/postgres-table-schema-column';
|
import { PostgresTableSchemaColumn } from 'src/engine/metadata-modules/remote-server/types/postgres-table-schema-column';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnAction,
|
WorkspaceMigrationColumnAction,
|
||||||
WorkspaceMigrationColumnCreate,
|
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationColumnCreate,
|
||||||
WorkspaceMigrationColumnDrop,
|
WorkspaceMigrationColumnDrop,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
@ -33,6 +33,8 @@ export class RemoteTableSchemaUpdateService {
|
|||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
columnName: columnAdded.name,
|
columnName: columnAdded.name,
|
||||||
columnType: columnAdded.type,
|
columnType: columnAdded.type,
|
||||||
|
isNullable: true,
|
||||||
|
defaultValue: null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const columnsDeletedUpdates: WorkspaceMigrationColumnDrop[] =
|
const columnsDeletedUpdates: WorkspaceMigrationColumnDrop[] =
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
|
||||||
import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface';
|
|
||||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||||
|
import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface';
|
||||||
|
|
||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||||
|
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
||||||
|
import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory';
|
||||||
|
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
WorkspaceMigrationColumnAlter,
|
WorkspaceMigrationColumnAlter,
|
||||||
WorkspaceMigrationColumnCreate,
|
WorkspaceMigrationColumnCreate,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
|
||||||
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
|
||||||
import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory';
|
|
||||||
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationException,
|
WorkspaceMigrationException,
|
||||||
WorkspaceMigrationExceptionCode,
|
WorkspaceMigrationExceptionCode,
|
||||||
@ -48,7 +48,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
|||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
columnName,
|
columnName,
|
||||||
columnType: fieldMetadataTypeToColumnType(fieldMetadata.type),
|
columnType: fieldMetadataTypeToColumnType(fieldMetadata.type),
|
||||||
isNullable: fieldMetadata.isNullable,
|
isNullable: fieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializedDefaultValue,
|
defaultValue: serializedDefaultValue,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -81,7 +81,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
|||||||
currentColumnDefinition: {
|
currentColumnDefinition: {
|
||||||
columnName: currentColumnName,
|
columnName: currentColumnName,
|
||||||
columnType: fieldMetadataTypeToColumnType(currentFieldMetadata.type),
|
columnType: fieldMetadataTypeToColumnType(currentFieldMetadata.type),
|
||||||
isNullable: currentFieldMetadata.isNullable,
|
isNullable: currentFieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializeDefaultValue(
|
defaultValue: serializeDefaultValue(
|
||||||
currentFieldMetadata.defaultValue,
|
currentFieldMetadata.defaultValue,
|
||||||
),
|
),
|
||||||
@ -89,7 +89,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
|||||||
alteredColumnDefinition: {
|
alteredColumnDefinition: {
|
||||||
columnName: alteredColumnName,
|
columnName: alteredColumnName,
|
||||||
columnType: fieldMetadataTypeToColumnType(alteredFieldMetadata.type),
|
columnType: fieldMetadataTypeToColumnType(alteredFieldMetadata.type),
|
||||||
isNullable: alteredFieldMetadata.isNullable,
|
isNullable: alteredFieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializedDefaultValue,
|
defaultValue: serializedDefaultValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
|
||||||
import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface';
|
|
||||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||||
|
import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface';
|
||||||
|
|
||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||||
|
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
||||||
|
import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory';
|
||||||
|
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
WorkspaceMigrationColumnAlter,
|
WorkspaceMigrationColumnAlter,
|
||||||
WorkspaceMigrationColumnCreate,
|
WorkspaceMigrationColumnCreate,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
|
||||||
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
|
||||||
import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory';
|
|
||||||
import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationException,
|
WorkspaceMigrationException,
|
||||||
WorkspaceMigrationExceptionCode,
|
WorkspaceMigrationExceptionCode,
|
||||||
@ -45,7 +45,7 @@ export class EnumColumnActionFactory extends ColumnActionAbstractFactory<EnumFie
|
|||||||
columnType: fieldMetadataTypeToColumnType(fieldMetadata.type),
|
columnType: fieldMetadataTypeToColumnType(fieldMetadata.type),
|
||||||
enum: enumOptions,
|
enum: enumOptions,
|
||||||
isArray: fieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
isArray: fieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
||||||
isNullable: fieldMetadata.isNullable,
|
isNullable: fieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializedDefaultValue,
|
defaultValue: serializedDefaultValue,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -102,7 +102,7 @@ export class EnumColumnActionFactory extends ColumnActionAbstractFactory<EnumFie
|
|||||||
? [...currentFieldMetadata.options.map((option) => option.value)]
|
? [...currentFieldMetadata.options.map((option) => option.value)]
|
||||||
: undefined,
|
: undefined,
|
||||||
isArray: currentFieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
isArray: currentFieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
||||||
isNullable: currentFieldMetadata.isNullable,
|
isNullable: currentFieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializeDefaultValue(
|
defaultValue: serializeDefaultValue(
|
||||||
currentFieldMetadata.defaultValue,
|
currentFieldMetadata.defaultValue,
|
||||||
),
|
),
|
||||||
@ -112,7 +112,7 @@ export class EnumColumnActionFactory extends ColumnActionAbstractFactory<EnumFie
|
|||||||
columnType: fieldMetadataTypeToColumnType(alteredFieldMetadata.type),
|
columnType: fieldMetadataTypeToColumnType(alteredFieldMetadata.type),
|
||||||
enum: enumOptions,
|
enum: enumOptions,
|
||||||
isArray: alteredFieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
isArray: alteredFieldMetadata.type === FieldMetadataType.MULTI_SELECT,
|
||||||
isNullable: alteredFieldMetadata.isNullable,
|
isNullable: alteredFieldMetadata.isNullable ?? true,
|
||||||
defaultValue: serializedDefaultValue,
|
defaultValue: serializedDefaultValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -28,8 +28,8 @@ export interface WorkspaceMigrationColumnDefinition {
|
|||||||
columnType: string;
|
columnType: string;
|
||||||
enum?: WorkspaceMigrationEnum[];
|
enum?: WorkspaceMigrationEnum[];
|
||||||
isArray?: boolean;
|
isArray?: boolean;
|
||||||
isNullable?: boolean;
|
isNullable: boolean;
|
||||||
defaultValue?: any;
|
defaultValue: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceMigrationIndexAction {
|
export interface WorkspaceMigrationIndexAction {
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-s
|
|||||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||||
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
|
|
||||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
import { CleanInactiveWorkspacesCommandOptions } from 'src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command';
|
import { CleanInactiveWorkspacesCommandOptions } from 'src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command';
|
||||||
import { getDryRunLogHeader } from 'src/utils/get-dry-run-log-header';
|
import { getDryRunLogHeader } from 'src/utils/get-dry-run-log-header';
|
||||||
@ -39,7 +38,7 @@ export class CleanInactiveWorkspaceJob {
|
|||||||
private readonly inactiveDaysBeforeEmail;
|
private readonly inactiveDaysBeforeEmail;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(WorkspaceEntity, 'core')
|
@InjectRepository(Workspace, 'core')
|
||||||
private readonly workspaceRepository: Repository<Workspace>,
|
private readonly workspaceRepository: Repository<Workspace>,
|
||||||
private readonly dataSourceService: DataSourceService,
|
private readonly dataSourceService: DataSourceService,
|
||||||
private readonly objectMetadataService: ObjectMetadataService,
|
private readonly objectMetadataService: ObjectMetadataService,
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { isDefined } from 'class-validator';
|
||||||
import { QueryRunner, TableColumn } from 'typeorm';
|
import { QueryRunner, TableColumn } from 'typeorm';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { isDefined } from 'class-validator';
|
|
||||||
|
|
||||||
|
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
||||||
|
import { unserializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/unserialize-default-value';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnAlter,
|
WorkspaceMigrationColumnAlter,
|
||||||
WorkspaceMigrationRenamedEnum,
|
WorkspaceMigrationRenamedEnum,
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceMigrationEnumService {
|
export class WorkspaceMigrationEnumService {
|
||||||
@ -111,11 +112,17 @@ export class WorkspaceMigrationEnumService {
|
|||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private migrateEnumValue(
|
private migrateEnumValue({
|
||||||
value: string,
|
value,
|
||||||
renamedEnumValues?: WorkspaceMigrationRenamedEnum[],
|
renamedEnumValues,
|
||||||
allEnumValues?: string[],
|
allEnumValues,
|
||||||
) {
|
defaultValueFallback,
|
||||||
|
}: {
|
||||||
|
value: string;
|
||||||
|
renamedEnumValues?: WorkspaceMigrationRenamedEnum[];
|
||||||
|
allEnumValues?: string[];
|
||||||
|
defaultValueFallback?: string;
|
||||||
|
}) {
|
||||||
if (renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to) {
|
if (renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to) {
|
||||||
return renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to;
|
return renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to;
|
||||||
}
|
}
|
||||||
@ -124,6 +131,10 @@ export class WorkspaceMigrationEnumService {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDefined(defaultValueFallback)) {
|
||||||
|
return defaultValueFallback;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,16 +163,23 @@ export class WorkspaceMigrationEnumService {
|
|||||||
.split(',')
|
.split(',')
|
||||||
.map((v: string) => v.trim())
|
.map((v: string) => v.trim())
|
||||||
.map((v: string) =>
|
.map((v: string) =>
|
||||||
this.migrateEnumValue(v, renamedEnumValues, enumValues),
|
this.migrateEnumValue({
|
||||||
|
value: v,
|
||||||
|
renamedEnumValues: renamedEnumValues,
|
||||||
|
allEnumValues: enumValues,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.filter((v: string | null) => isDefined(v)),
|
.filter((v: string | null) => isDefined(v)),
|
||||||
);
|
);
|
||||||
} else if (typeof val === 'string') {
|
} else if (typeof val === 'string') {
|
||||||
const migratedValue = this.migrateEnumValue(
|
const migratedValue = this.migrateEnumValue({
|
||||||
val,
|
value: val,
|
||||||
renamedEnumValues,
|
renamedEnumValues: renamedEnumValues,
|
||||||
enumValues,
|
allEnumValues: enumValues,
|
||||||
);
|
defaultValueFallback: columnDefinition.isNullable
|
||||||
|
? null
|
||||||
|
: unserializeDefaultValue(columnDefinition.defaultValue),
|
||||||
|
});
|
||||||
|
|
||||||
val = isDefined(migratedValue) ? `'${migratedValue}'` : null;
|
val = isDefined(migratedValue) ? `'${migratedValue}'` : null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user