From f69b78aef6c6d28106de76b86fbb59c7005feb62 Mon Sep 17 00:00:00 2001 From: Steve Reis <stevereis@gmail.com> Date: Wed, 15 Sep 2021 17:00:31 +0200 Subject: [PATCH] WIP graphql pathologies Added flatten groups --- .../common/interfaces/utilities.interface.ts | 1 + .../connectors/datashield/main.connector.ts | 5 + .../exareme/interfaces/hierarchy.interface.ts | 8 ++ .../exareme/interfaces/pathology.interface.ts | 9 ++ .../interfaces/variable-entity.interface.ts | 9 ++ .../exareme/interfaces/variable.interface.ts | 4 + .../connectors/exareme/main.connector.ts | 93 ++++++++++++++++++- api/src/engine/engine.interfaces.ts | 3 + api/src/engine/engine.resolver.ts | 17 +--- 9 files changed, 134 insertions(+), 15 deletions(-) create mode 100644 api/src/common/interfaces/utilities.interface.ts create mode 100644 api/src/engine/connectors/exareme/interfaces/hierarchy.interface.ts create mode 100644 api/src/engine/connectors/exareme/interfaces/pathology.interface.ts create mode 100644 api/src/engine/connectors/exareme/interfaces/variable-entity.interface.ts create mode 100644 api/src/engine/connectors/exareme/interfaces/variable.interface.ts diff --git a/api/src/common/interfaces/utilities.interface.ts b/api/src/common/interfaces/utilities.interface.ts new file mode 100644 index 0000000..f226c24 --- /dev/null +++ b/api/src/common/interfaces/utilities.interface.ts @@ -0,0 +1 @@ +export type Dictionary<T> = { [key: string]: T }; \ No newline at end of file diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts index a362265..104a4fe 100644 --- a/api/src/engine/connectors/datashield/main.connector.ts +++ b/api/src/engine/connectors/datashield/main.connector.ts @@ -1,7 +1,12 @@ import { Observable } from 'rxjs'; import { IEngineService } from 'src/engine/engine.interfaces'; +import { Domain } from 'src/engine/models/domain.model'; export default class DataShieldService implements IEngineService { + getDomain(): Domain[] { + throw new Error('Method not implemented.'); + } + demo(): string { return 'datashield'; } diff --git a/api/src/engine/connectors/exareme/interfaces/hierarchy.interface.ts b/api/src/engine/connectors/exareme/interfaces/hierarchy.interface.ts new file mode 100644 index 0000000..6d0f02b --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/hierarchy.interface.ts @@ -0,0 +1,8 @@ +import { VariableEntity } from "./variable-entity.interface"; + +export interface Hierarchy { + code: string; + label: string; + groups: Hierarchy[]; + variables: VariableEntity[]; +} \ No newline at end of file diff --git a/api/src/engine/connectors/exareme/interfaces/pathology.interface.ts b/api/src/engine/connectors/exareme/interfaces/pathology.interface.ts new file mode 100644 index 0000000..d9dbea5 --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/pathology.interface.ts @@ -0,0 +1,9 @@ +import { Hierarchy } from "./Hierarchy.interface"; +import { VariableEntity } from "./variable-entity.interface"; + +export interface Pathology { + code: string; + label: string; + datasets: VariableEntity[]; + metadataHierarchy: Hierarchy; +} \ No newline at end of file diff --git a/api/src/engine/connectors/exareme/interfaces/variable-entity.interface.ts b/api/src/engine/connectors/exareme/interfaces/variable-entity.interface.ts new file mode 100644 index 0000000..ce1ce25 --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/variable-entity.interface.ts @@ -0,0 +1,9 @@ +import { Variable } from "./variable.interface"; + +export interface VariableEntity extends Variable { + type?: 'nominal' | 'ordinal' | 'real' | 'integer' | 'text' | 'date'; + description?: string; + enumerations?: Variable[]; + group?: Variable[]; + info?: string; +} \ No newline at end of file diff --git a/api/src/engine/connectors/exareme/interfaces/variable.interface.ts b/api/src/engine/connectors/exareme/interfaces/variable.interface.ts new file mode 100644 index 0000000..85174c8 --- /dev/null +++ b/api/src/engine/connectors/exareme/interfaces/variable.interface.ts @@ -0,0 +1,4 @@ +export interface Variable { + code: string; + label?: string; +} \ No newline at end of file diff --git a/api/src/engine/connectors/exareme/main.connector.ts b/api/src/engine/connectors/exareme/main.connector.ts index b85b494..ae59036 100644 --- a/api/src/engine/connectors/exareme/main.connector.ts +++ b/api/src/engine/connectors/exareme/main.connector.ts @@ -1,13 +1,57 @@ import { HttpService } from '@nestjs/axios'; import { Request } from 'express'; -import { map, Observable } from 'rxjs'; +import { firstValueFrom, map, Observable } from 'rxjs'; +import { Dictionary } from 'src/common/interfaces/utilities.interface'; import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces'; +import { Domain } from 'src/engine/models/domain.model'; +import { Group } from 'src/engine/models/group.model'; +import { Hierarchy } from './interfaces/Hierarchy.interface'; +import { Pathology } from './interfaces/pathology.interface'; +import { VariableEntity } from './interfaces/variable-entity.interface'; export default class ExaremeService implements IEngineService { constructor( private readonly options: IEngineOptions, private readonly httpService: HttpService, - ) {} + ) { } + + private hierarchyToGroup = (data: Hierarchy): Group => { + return { + id: data.code, + label: data.label, + groups: data.groups ? data.groups.map((child: Hierarchy) => this.hierarchyToGroup(child)) : [], + variables: [] + } + } + + private flattenGroups = (data: Hierarchy): Group[] => { + let groups: Group[] = [this.hierarchyToGroup(data)]; + + if (data.groups) { + groups = groups.concat(data.groups.flatMap(this.flattenGroups)); + } + + return groups; + } + + + async getDomain(): Promise<Domain[]> { + const path = this.options.baseurl + 'pathologies'; + + const data = await firstValueFrom(this.httpService.get(path)); + + const domains = data.data.map((data: Pathology): Domain => { + return { + id: data.code, + label: data.label, + groups: data.metadataHierarchy.groups.flatMap(this.flattenGroups), + datasets: [], + variables: [], + } + }) + + return domains; + } demo(): string { return 'exareme'; @@ -82,4 +126,49 @@ export default class ExaremeService implements IEngineService { .get<string>(path) .pipe(map((response) => response.data)); } + + private pathologiesHierarchies = ( + json: Pathology[] + ): Dictionary<Hierarchy> => { + const pathologiesDatasets: Dictionary<Hierarchy> = {}; + json.forEach(pathology => { + pathologiesDatasets[pathology.code] = pathology.metadataHierarchy; + }); + + return pathologiesDatasets; + }; + + private pathologiesVariables = (json: Pathology[]): Dictionary<VariableEntity[]> => { + const pathologiesVariables: Dictionary<VariableEntity[]> = {}; + json.forEach(pathology => { + let variables: VariableEntity[] = []; + + const dummyAccumulator = (node: any): void => { + if (node.variables) { + variables = [...variables, ...node.variables]; + } + + if (node.groups) { + return node.groups.map(dummyAccumulator); + } + }; + + if (pathology) { + dummyAccumulator(pathology.metadataHierarchy); + } + + pathologiesVariables[pathology.code] = variables; + }); + + return pathologiesVariables; + }; + + private pathologiesDatasets = (json: Pathology[]): Dictionary<VariableEntity[]> => { + const pathologiesDatasets: Dictionary<VariableEntity[]> = {}; + json.forEach(pathology => { + pathologiesDatasets[pathology.code] = pathology.datasets; + }); + + return pathologiesDatasets; + }; } diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/engine.interfaces.ts index 22f4a54..17db7ff 100644 --- a/api/src/engine/engine.interfaces.ts +++ b/api/src/engine/engine.interfaces.ts @@ -1,5 +1,6 @@ import { Request } from 'express'; import { Observable } from 'rxjs'; +import { Domain } from './models/domain.model'; export interface IEngineOptions { type: string; @@ -9,6 +10,8 @@ export interface IEngineOptions { export interface IEngineService { demo(): string; + getDomain(): Domain[] | Promise<Domain[]>; + getAlgorithms(request: Request): Observable<string>; getExperiments(request: Request): Observable<string>; diff --git a/api/src/engine/engine.resolver.ts b/api/src/engine/engine.resolver.ts index 0e4687c..6adcf0d 100644 --- a/api/src/engine/engine.resolver.ts +++ b/api/src/engine/engine.resolver.ts @@ -8,19 +8,10 @@ import { Domain } from './models/domain.model'; export class EngineResolver { constructor( @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService, - ) {} + ) { } - @Query(() => Domain) - async hello() { - const dummy: Domain = { - id: 'test', - label: 'test', - description: 'test', - groups: [], - variables: [], - datasets: [], - }; - - return dummy; + @Query(() => [Domain]) + async domain() { + return this.engineService.getDomain(); } } -- GitLab