Aggregated queries #1 (#8345)

First step of https://github.com/twentyhq/twenty/issues/6868

Adds min.., max.. queries for DATETIME fields
adds min.., max.., avg.., sum.. queries for NUMBER fields 

(count distinct operation and composite fields such as CURRENCY handling
will be dealt with in a future PR)

<img width="1422" alt="Capture d’écran 2024-11-06 à 15 48 46"
src="https://github.com/user-attachments/assets/4bcdece0-ad3e-4536-9720-fe4044a36719">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Marie
2024-11-14 18:05:05 +01:00
committed by GitHub
parent c966533f26
commit a799370483
93 changed files with 1590 additions and 1178 deletions

View File

@ -10,7 +10,7 @@ import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-me
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { isEnumFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util';
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
import { FieldMetadataMap } from 'src/engine/metadata-modules/utils/generate-object-metadata-map.util';
import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metadata-map';
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
@ -20,10 +20,10 @@ type EntitySchemaColumnMap = {
@Injectable()
export class EntitySchemaColumnFactory {
create(fieldMetadataMap: FieldMetadataMap): EntitySchemaColumnMap {
create(fieldMetadataMapByName: FieldMetadataMap): EntitySchemaColumnMap {
let entitySchemaColumnMap: EntitySchemaColumnMap = {};
const fieldMetadataCollection = Object.values(fieldMetadataMap);
const fieldMetadataCollection = Object.values(fieldMetadataMapByName);
for (const fieldMetadata of fieldMetadataCollection) {
const key = fieldMetadata.name;

View File

@ -2,10 +2,8 @@ import { Injectable } from '@nestjs/common';
import { EntitySchemaRelationOptions } from 'typeorm';
import {
FieldMetadataMap,
ObjectMetadataMap,
} from 'src/engine/metadata-modules/utils/generate-object-metadata-map.util';
import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metadata-map';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
import { determineRelationDetails } from 'src/engine/twenty-orm/utils/determine-relation-details.util';
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
@ -18,12 +16,12 @@ export class EntitySchemaRelationFactory {
constructor() {}
async create(
fieldMetadataMap: FieldMetadataMap,
objectMetadataMap: ObjectMetadataMap,
fieldMetadataMapByName: FieldMetadataMap,
objectMetadataMaps: ObjectMetadataMaps,
): Promise<EntitySchemaRelationMap> {
const entitySchemaRelationMap: EntitySchemaRelationMap = {};
const fieldMetadataCollection = Object.values(fieldMetadataMap);
const fieldMetadataCollection = Object.values(fieldMetadataMapByName);
for (const fieldMetadata of fieldMetadataCollection) {
if (!isRelationFieldMetadataType(fieldMetadata.type)) {
@ -42,7 +40,7 @@ export class EntitySchemaRelationFactory {
const relationDetails = await determineRelationDetails(
fieldMetadata,
relationMetadata,
objectMetadataMap,
objectMetadataMaps,
);
entitySchemaRelationMap[fieldMetadata.name] = {

View File

@ -2,10 +2,8 @@ import { Injectable } from '@nestjs/common';
import { EntitySchema } from 'typeorm';
import {
ObjectMetadataMap,
ObjectMetadataMapItem,
} from 'src/engine/metadata-modules/utils/generate-object-metadata-map.util';
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
import { EntitySchemaColumnFactory } from 'src/engine/twenty-orm/factories/entity-schema-column.factory';
import { EntitySchemaRelationFactory } from 'src/engine/twenty-orm/factories/entity-schema-relation.factory';
import { WorkspaceEntitiesStorage } from 'src/engine/twenty-orm/storage/workspace-entities.storage';
@ -20,17 +18,17 @@ export class EntitySchemaFactory {
async create(
workspaceId: string,
metadataVersion: number,
objectMetadata: ObjectMetadataMapItem,
objectMetadataMap: ObjectMetadataMap,
_metadataVersion: number,
objectMetadata: ObjectMetadataItemWithFieldMaps,
objectMetadataMaps: ObjectMetadataMaps,
): Promise<EntitySchema> {
const columns = this.entitySchemaColumnFactory.create(
objectMetadata.fields,
objectMetadata.fieldsByName,
);
const relations = await this.entitySchemaRelationFactory.create(
objectMetadata.fields,
objectMetadataMap,
objectMetadata.fieldsByName,
objectMetadataMaps,
);
const entitySchema = new EntitySchema({

View File

@ -86,13 +86,13 @@ export class WorkspaceDatasourceFactory {
let cachedEntitySchemas: EntitySchema[];
const cachedObjectMetadataMap =
await this.workspaceCacheStorageService.getObjectMetadataMap(
const cachedObjectMetadataMaps =
await this.workspaceCacheStorageService.getObjectMetadataMaps(
workspaceId,
cachedWorkspaceMetadataVersion,
);
if (!cachedObjectMetadataMap) {
if (!cachedObjectMetadataMaps) {
throw new TwentyORMException(
`Workspace Schema not found for workspace ${workspaceId}`,
TwentyORMExceptionCode.METADATA_COLLECTION_NOT_FOUND,
@ -105,13 +105,14 @@ export class WorkspaceDatasourceFactory {
);
} else {
const entitySchemas = await Promise.all(
Object.values(cachedObjectMetadataMap).map((objectMetadata) =>
this.entitySchemaFactory.create(
workspaceId,
cachedWorkspaceMetadataVersion,
objectMetadata,
cachedObjectMetadataMap,
),
Object.values(cachedObjectMetadataMaps.byId).map(
(objectMetadata) =>
this.entitySchemaFactory.create(
workspaceId,
cachedWorkspaceMetadataVersion,
objectMetadata,
cachedObjectMetadataMaps,
),
),
);
@ -127,7 +128,7 @@ export class WorkspaceDatasourceFactory {
const workspaceDataSource = new WorkspaceDataSource(
{
workspaceId,
objectMetadataMap: cachedObjectMetadataMap,
objectMetadataMaps: cachedObjectMetadataMaps,
},
{
url: