feat: drop target column map (#4670)

This PR is dropping the column `targetColumnMap` of fieldMetadata
entities.
The goal of this column was to properly map field to their respecting
column in the table.
We decide to drop it and instead compute the column name on the fly when
we need it, as it's more easier to support.
Some parts of the code has been refactored to try making implementation
of composite type more easier to understand and maintain.

Fix #3760

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2024-04-08 16:00:28 +02:00
committed by GitHub
parent 84f8c14e52
commit 5019b5febc
72 changed files with 1432 additions and 1853 deletions

View File

@ -1,19 +1,9 @@
import { createCompositeFieldKey } from 'src/engine/api/graphql/workspace-query-builder/utils/composite-field-metadata.util';
import {
isSpecialKey,
handleSpecialKey,
handleCompositeKey,
parseResult,
} from 'src/engine/api/graphql/workspace-query-runner/utils/parse-result.util';
describe('isSpecialKey', () => {
test('should return true if the key starts with "___"', () => {
expect(isSpecialKey('___specialKey')).toBe(true);
});
test('should return false if the key does not start with "___"', () => {
expect(isSpecialKey('normalKey')).toBe(false);
});
});
describe('handleSpecialKey', () => {
let result;
@ -21,8 +11,12 @@ describe('handleSpecialKey', () => {
result = {};
});
test('should correctly process a special key and add it to the result object', () => {
handleSpecialKey(result, '___complexField_link', 'value1');
test('should correctly process a composite key and add it to the result object', () => {
handleCompositeKey(
result,
createCompositeFieldKey('complexField', 'link'),
'value1',
);
expect(result).toEqual({
complexField: {
link: 'value1',
@ -31,8 +25,16 @@ describe('handleSpecialKey', () => {
});
test('should add values under the same newKey if called multiple times', () => {
handleSpecialKey(result, '___complexField_link', 'value1');
handleSpecialKey(result, '___complexField_text', 'value2');
handleCompositeKey(
result,
createCompositeFieldKey('complexField', 'link'),
'value1',
);
handleCompositeKey(
result,
createCompositeFieldKey('complexField', 'text'),
'value2',
);
expect(result).toEqual({
complexField: {
link: 'value1',
@ -41,8 +43,8 @@ describe('handleSpecialKey', () => {
});
});
test('should not create a new field if the special key is not correctly formed', () => {
handleSpecialKey(result, '___complexField', 'value1');
test('should not create a new field if the composite key is not correctly formed', () => {
handleCompositeKey(result, 'COMPOSITE___complexField', 'value1');
expect(result).toEqual({});
});
});
@ -51,9 +53,9 @@ describe('parseResult', () => {
test('should recursively parse an object and handle special keys', () => {
const obj = {
normalField: 'value1',
___specialField_part1: 'value2',
COMPOSITE___specialField_part1: 'value2',
nested: {
___specialFieldNested_part2: 'value3',
COMPOSITE___specialFieldNested_part2: 'value3',
},
};
@ -75,10 +77,10 @@ describe('parseResult', () => {
test('should handle arrays and parse each element', () => {
const objArray = [
{
___specialField_part1: 'value1',
COMPOSITE___specialField_part1: 'value1',
},
{
___specialField_part2: 'value2',
COMPOSITE___specialField_part2: 'value2',
},
];

View File

@ -1,27 +1,25 @@
export const isSpecialKey = (key: string): boolean => {
return key.startsWith('___');
};
import {
isPrefixedCompositeField,
parseCompositeFieldKey,
} from 'src/engine/api/graphql/workspace-query-builder/utils/composite-field-metadata.util';
export const handleSpecialKey = (
export const handleCompositeKey = (
result: any,
key: string,
value: any,
): void => {
const parts = key.split('_').filter((part) => part);
const parsedFieldKey = parseCompositeFieldKey(key);
// If parts don't contain enough information, return without altering result
if (parts.length < 2) {
// If composite field key can't be parsed, return
if (!parsedFieldKey) {
return;
}
const newKey = parts.slice(0, -1).join('');
const subKey = parts[parts.length - 1];
if (!result[newKey]) {
result[newKey] = {};
if (!result[parsedFieldKey.parentFieldName]) {
result[parsedFieldKey.parentFieldName] = {};
}
result[newKey][subKey] = value;
result[parsedFieldKey.parentFieldName][parsedFieldKey.childFieldName] = value;
};
export const parseResult = (obj: any): any => {
@ -41,8 +39,8 @@ export const parseResult = (obj: any): any => {
result[key] = parseResult(obj[key]);
} else if (key === '__typename') {
result[key] = obj[key].replace(/^_*/, '');
} else if (isSpecialKey(key)) {
handleSpecialKey(result, key, obj[key]);
} else if (isPrefixedCompositeField(key)) {
handleCompositeKey(result, key, obj[key]);
} else {
result[key] = obj[key];
}