diff --git a/server/src/metadata/field-metadata/services/field-metadata.service.ts b/server/src/metadata/field-metadata/services/field-metadata.service.ts index f771b21b7..36a418541 100644 --- a/server/src/metadata/field-metadata/services/field-metadata.service.ts +++ b/server/src/metadata/field-metadata/services/field-metadata.service.ts @@ -83,7 +83,11 @@ export class FieldMetadataService extends TypeOrmQueryService { const createdFieldMetadata = await super.createOne({ ...record, - targetColumnMap: generateTargetColumnMap(record.type), + targetColumnMap: generateTargetColumnMap( + record.type, + record.isCustom, + record.name, + ), }); await this.tenantMigrationService.createCustomMigration( diff --git a/server/src/metadata/field-metadata/utils/field-metadata.util.spec.ts b/server/src/metadata/field-metadata/utils/field-metadata.util.spec.ts new file mode 100644 index 000000000..187fd16d2 --- /dev/null +++ b/server/src/metadata/field-metadata/utils/field-metadata.util.spec.ts @@ -0,0 +1,57 @@ +import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; + +import { + generateTargetColumnMap, + convertFieldMetadataToColumnActions, +} from './field-metadata.util'; + +describe('generateTargetColumnMap', () => { + it('should generate a target column map for a given type', () => { + const textMap = generateTargetColumnMap( + FieldMetadataType.TEXT, + false, + 'name', + ); + expect(textMap).toEqual({ value: 'name' }); + + const urlMap = generateTargetColumnMap( + FieldMetadataType.URL, + false, + 'website', + ); + expect(urlMap).toEqual({ text: 'website_text', link: 'website_link' }); + + const moneyMap = generateTargetColumnMap( + FieldMetadataType.MONEY, + true, + 'price', + ); + expect(moneyMap).toEqual({ + amount: '_price_amount', + currency: '_price_currency', + }); + }); + + it('should throw an error for an unknown type', () => { + expect(() => + generateTargetColumnMap('invalid' as FieldMetadataType, false, 'name'), + ).toThrowError('Unknown type invalid'); + }); +}); + +describe('convertFieldMetadataToColumnActions', () => { + it('should convert field metadata to column actions', () => { + const fieldMetadata = { + type: FieldMetadataType.TEXT, + targetColumnMap: { value: 'name' }, + } as any; + const columnActions = convertFieldMetadataToColumnActions(fieldMetadata); + expect(columnActions).toEqual([ + { + action: 'CREATE', + columnName: 'name', + columnType: 'text', + }, + ]); + }); +}); diff --git a/server/src/metadata/field-metadata/utils/field-metadata.util.ts b/server/src/metadata/field-metadata/utils/field-metadata.util.ts index 25dde7920..1e55fbf5c 100644 --- a/server/src/metadata/field-metadata/utils/field-metadata.util.ts +++ b/server/src/metadata/field-metadata/utils/field-metadata.util.ts @@ -1,8 +1,5 @@ -import { v4 } from 'uuid'; - import { FieldMetadataTargetColumnMap } from 'src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface'; -import { uuidToBase36 } from 'src/metadata/data-source/data-source.util'; import { FieldMetadata, FieldMetadataType, @@ -12,16 +9,6 @@ import { TenantMigrationColumnActionType, } from 'src/metadata/tenant-migration/tenant-migration.entity'; -/** - * Generate a column name from a field name removing unsupported characters. - * - * @param name string - * @returns string - */ -export function generateColumnName(name: string): string { - return name.toLowerCase().replace(/ /g, '_'); -} - /** * Generate a target column map for a given type, this is used to map the field to the correct column(s) in the database. * This is used to support fields that map to multiple columns in the database. @@ -31,7 +18,11 @@ export function generateColumnName(name: string): string { */ export function generateTargetColumnMap( type: FieldMetadataType, + isCustomField: boolean, + fieldName: string, ): FieldMetadataTargetColumnMap { + const columnName = isCustomField ? `_${fieldName}` : fieldName; + switch (type) { case FieldMetadataType.TEXT: case FieldMetadataType.PHONE: @@ -40,17 +31,17 @@ export function generateTargetColumnMap( case FieldMetadataType.BOOLEAN: case FieldMetadataType.DATE: return { - value: `column_${uuidToBase36(v4())}`, + value: columnName, }; case FieldMetadataType.URL: return { - text: `column_${uuidToBase36(v4())}`, - link: `column_${uuidToBase36(v4())}`, + text: `${columnName}_text`, + link: `${columnName}_link`, }; case FieldMetadataType.MONEY: return { - amount: `column_${uuidToBase36(v4())}`, - currency: `column_${uuidToBase36(v4())}`, + amount: `${columnName}_amount`, + currency: `${columnName}_currency`, }; default: throw new Error(`Unknown type ${type}`); diff --git a/server/src/metadata/object-metadata/hooks/before-create-one-object.hook.ts b/server/src/metadata/object-metadata/hooks/before-create-one-object.hook.ts index 79f1677ff..b291d2bbd 100644 --- a/server/src/metadata/object-metadata/hooks/before-create-one-object.hook.ts +++ b/server/src/metadata/object-metadata/hooks/before-create-one-object.hook.ts @@ -30,7 +30,7 @@ export class BeforeCreateOneObject ); instance.input.dataSourceId = lastDataSourceMetadata.id; - instance.input.targetTableName = instance.input.namePlural; + instance.input.targetTableName = `_${instance.input.namePlural}`; instance.input.workspaceId = workspaceId; instance.input.isActive = true; instance.input.isCustom = true;