From e99bb300fad9a0882db8cf3225037255e074b18e Mon Sep 17 00:00:00 2001
From: Leonardo <leomilho@gmail.com>
Date: Tue, 28 Jan 2025 11:33:28 +0100
Subject: [PATCH] chore: use stats from tscommon

---
 src/frontend/statistics/graphStatistics.ts    |  92 -------------
 src/frontend/statistics/index.ts              |  27 ----
 .../statistics/tests/attributeStats.test.ts   | 107 ----------------
 .../statistics/tests/getAttributeType.test.ts |  65 ----------
 .../statistics/tests/graphStatistics.test.ts  | 121 ------------------
 .../statistics/utils/attributeStats/array.ts  |   6 -
 .../utils/attributeStats/boolean.ts           |   9 --
 .../utils/attributeStats/categorical.ts       |  15 ---
 .../statistics/utils/attributeStats/index.ts  |   7 -
 .../utils/attributeStats/initialize.ts        |  47 -------
 .../utils/attributeStats/numerical.ts         |   9 --
 .../statistics/utils/attributeStats/object.ts |   5 -
 .../utils/attributeStats/temporal.ts          |  10 --
 .../statistics/utils/getAttributeType.ts      |  78 -----------
 src/frontend/statistics/utils/index.ts        |   3 -
 .../statistics/utils/updateStatistics.ts      |  45 -------
 src/readers/queryService.ts                   |   6 +-
 17 files changed, 2 insertions(+), 650 deletions(-)
 delete mode 100644 src/frontend/statistics/graphStatistics.ts
 delete mode 100644 src/frontend/statistics/index.ts
 delete mode 100644 src/frontend/statistics/tests/attributeStats.test.ts
 delete mode 100644 src/frontend/statistics/tests/getAttributeType.test.ts
 delete mode 100644 src/frontend/statistics/tests/graphStatistics.test.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/array.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/boolean.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/categorical.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/index.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/initialize.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/numerical.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/object.ts
 delete mode 100644 src/frontend/statistics/utils/attributeStats/temporal.ts
 delete mode 100644 src/frontend/statistics/utils/getAttributeType.ts
 delete mode 100644 src/frontend/statistics/utils/index.ts
 delete mode 100644 src/frontend/statistics/utils/updateStatistics.ts

diff --git a/src/frontend/statistics/graphStatistics.ts b/src/frontend/statistics/graphStatistics.ts
deleted file mode 100644
index 904223d..0000000
--- a/src/frontend/statistics/graphStatistics.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import type { GraphQueryResultFromBackend, GraphStatistics } from 'ts-common';
-import { getAttributeType, initializeStatistics, updateStatistics } from './utils';
-
-export const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics => {
-  const { nodes, edges } = graph;
-
-  const n_nodes = nodes.length;
-  const n_edges = edges.length;
-
-  const density = n_nodes < 2 ? 0 : (n_edges * 2) / (n_nodes * (n_nodes - 1));
-
-  // general nodes and edges statistics
-  const metaData: GraphStatistics = {
-    topological: { density, self_loops: 0 },
-    nodes: { labels: [], count: n_nodes, types: {} },
-    edges: { labels: [], count: n_edges, types: {} },
-  };
-  // return metaData;
-
-  // attributes based statistics
-  // Pre-initialize maps for faster lookups
-  const seenNodeTypes = new Set();
-
-  for (let i = 0; i < nodes.length; i++) {
-    const node = nodes[i];
-    const nodeType = node.label;
-
-    // Use Set for faster existence checks
-    if (!seenNodeTypes.has(nodeType)) {
-      seenNodeTypes.add(nodeType);
-      metaData.nodes.labels.push(nodeType);
-      metaData.nodes.types[nodeType] = { count: 0, attributes: {} };
-    }
-
-    const nodeTypeStats = metaData.nodes.types[nodeType];
-    nodeTypeStats.count++;
-
-    const attributes = node.attributes;
-    const nodeTypeAttributes = nodeTypeStats.attributes;
-
-    const attributeEntries = Object.entries(attributes);
-    for (let j = 0; j < attributeEntries.length; j++) {
-      const [attributeId, attributeValue] = attributeEntries[j];
-      if (!nodeTypeAttributes[attributeId]) {
-        const attributeType = getAttributeType(attributeValue);
-        nodeTypeAttributes[attributeId] = {
-          attributeType,
-          statistics: initializeStatistics(attributeType),
-        };
-      }
-      updateStatistics(nodeTypeAttributes[attributeId], attributeValue);
-    }
-  }
-
-  // Process edges
-  // Pre-initialize sets and maps for faster lookups
-  const seenEdgeTypes = new Set();
-
-  for (let i = 0; i < edges.length; i++) {
-    const edge = edges[i];
-    const edgeType = edge.label;
-
-    // Use Set for faster existence checks
-    if (!seenEdgeTypes.has(edgeType)) {
-      seenEdgeTypes.add(edgeType);
-      metaData.edges.labels.push(edgeType);
-      metaData.edges.types[edgeType] = { count: 0, attributes: {} };
-    }
-
-    metaData.edges.types[edgeType].count++;
-
-    if (edge.from === edge.to) metaData.topological.self_loops++;
-
-    const edgeTypeAttributes = metaData.edges.types[edgeType].attributes;
-    const attributes = edge.attributes;
-
-    const attributeEntries = Object.entries(attributes);
-    for (let i = 0; i < attributeEntries.length; i++) {
-      const [attributeId, attributeValue] = attributeEntries[i];
-      if (!edgeTypeAttributes[attributeId]) {
-        const attributeType = getAttributeType(attributeValue);
-        edgeTypeAttributes[attributeId] = {
-          attributeType,
-          statistics: initializeStatistics(attributeType),
-        };
-      }
-      updateStatistics(edgeTypeAttributes[attributeId], attributeValue);
-    }
-  }
-
-  return metaData;
-};
diff --git a/src/frontend/statistics/index.ts b/src/frontend/statistics/index.ts
deleted file mode 100644
index 2d2a10f..0000000
--- a/src/frontend/statistics/index.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import type { EdgeQueryResult, GraphQueryResultFromBackend, GraphQueryResultMetaFromBackend, NodeQueryResult } from 'ts-common';
-import { getGraphStatistics } from './graphStatistics';
-
-export * from './graphStatistics';
-
-export const graphQueryBackend2graphQuery = (payload: GraphQueryResultFromBackend): GraphQueryResultMetaFromBackend => {
-  const nodeIDs = new Set();
-  const edgeIDs = new Set();
-
-  // Assign ids to a hidden attribute _id to better identify them
-  for (let i = 0; i < payload.nodes.length; i++) {
-    payload.nodes[i]._id = payload.nodes[i]._id || (payload.nodes[i] as any).id;
-    nodeIDs.add(payload.nodes[i]._id);
-  }
-  for (let i = 0; i < payload.edges.length; i++) {
-    payload.edges[i]._id = payload.edges[i]._id || (payload.edges[i] as any).id;
-    edgeIDs.add(payload.edges[i]._id);
-  }
-
-  // Only keep one node and one edge per id. This is also done in the backend, but we do it here as well to be sure.
-  const nodes = [...nodeIDs].map(nodeID => payload.nodes.find(node => node._id === nodeID) as unknown as NodeQueryResult);
-  const edges = [...edgeIDs].map(edgeID => payload.edges.find(edge => edge._id === edgeID) as unknown as EdgeQueryResult);
-
-  const metaData = getGraphStatistics(payload);
-
-  return { metaData, nodes, edges };
-};
diff --git a/src/frontend/statistics/tests/attributeStats.test.ts b/src/frontend/statistics/tests/attributeStats.test.ts
deleted file mode 100644
index 17f3093..0000000
--- a/src/frontend/statistics/tests/attributeStats.test.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { describe, it, expect } from 'bun:test';
-import {
-  updateArrayStats,
-  updateBooleanStats,
-  updateCategoricalStats,
-  updateNumericalStats,
-  updateTemporalStats,
-  updateObjectStats,
-  initializeStatistics,
-} from '../utils/attributeStats';
-import type { ArrayStats, BooleanStats, CategoricalStats, NumericalStats, TemporalStats, ObjectStats } from 'ts-common';
-
-describe('updateArrayStats', () => {
-  it('should update the length of the array', () => {
-    const stats: ArrayStats = { length: 0, count: 0 };
-    const value = [1, 2, 3];
-    updateArrayStats(stats, value);
-    expect(stats.length).toBe(3);
-    expect(stats.count).toBe(1);
-  });
-});
-
-describe('updateBooleanStats', () => {
-  it('should update true count when value is true', () => {
-    const stats: BooleanStats = { true: 0, false: 0 };
-    updateBooleanStats(stats, true);
-    expect(stats.true).toBe(1);
-    expect(stats.false).toBe(0);
-  });
-
-  it('should update false count when value is false', () => {
-    const stats: BooleanStats = { true: 0, false: 0 };
-    updateBooleanStats(stats, false);
-    expect(stats.false).toBe(1);
-    expect(stats.true).toBe(0);
-  });
-});
-
-describe('updateCategoricalStats', () => {
-  it('should update mode and unique items count', () => {
-    const stats: CategoricalStats = { uniqueItems: 0, values: [], mode: '', count: 0 };
-    updateCategoricalStats(stats, 'apple');
-    updateCategoricalStats(stats, 'banana');
-    updateCategoricalStats(stats, 'apple');
-
-    expect(stats.values).toEqual(['apple', 'banana', 'apple']);
-    expect(stats.uniqueItems).toBe(2);
-    expect(stats.mode).toBe('apple');
-    expect(stats.count).toBe(3);
-  });
-});
-
-describe('updateNumericalStats', () => {
-  it('should update min, max, average, and count', () => {
-    const stats: NumericalStats = { min: Infinity, max: -Infinity, average: 0, count: 0 };
-    updateNumericalStats(stats, 10);
-    updateNumericalStats(stats, 20);
-    updateNumericalStats(stats, 5);
-
-    expect(stats.min).toBe(5);
-    expect(stats.max).toBe(20);
-    expect(stats.average).toBeCloseTo(11.67, 2);
-    expect(stats.count).toBe(3);
-  });
-});
-
-describe('updateTemporalStats', () => {
-  it('should update min, max, and range for temporal values', () => {
-    const stats: TemporalStats = { min: Infinity, max: -Infinity, range: 0 };
-    updateTemporalStats(stats, '2022-01-01');
-    updateTemporalStats(stats, '2022-01-05');
-
-    expect(stats.min).toBe(new Date('2022-01-01').getTime());
-    expect(stats.max).toBe(new Date('2022-01-05').getTime());
-    expect(stats.range).toBe(new Date('2022-01-05').getTime() - new Date('2022-01-01').getTime());
-  });
-});
-
-describe('updateObjectStats', () => {
-  it('should update the length of the object keys', () => {
-    const stats: ObjectStats = { length: 0 };
-    const value = { key1: 'value1', key2: 'value2' };
-    updateObjectStats(stats, value);
-    expect(stats.length).toBe(2);
-  });
-});
-
-describe('initializeStatistics', () => {
-  it('should initialize statistics for string type', () => {
-    const stats = initializeStatistics('string');
-    expect(stats).toEqual({ uniqueItems: 0, values: [], mode: '', count: 0 });
-  });
-
-  it('should initialize statistics for boolean type', () => {
-    const stats = initializeStatistics('boolean');
-    expect(stats).toEqual({ true: 0, false: 0 });
-  });
-
-  it('should initialize statistics for number type', () => {
-    const stats = initializeStatistics('number');
-    expect(stats).toEqual({ min: Infinity, max: -Infinity, average: 0, count: 0 });
-  });
-
-  it('should throw an error for an unknown type', () => {
-    expect(() => initializeStatistics('unknown' as any)).toThrow('Unknown attribute type: unknown');
-  });
-});
diff --git a/src/frontend/statistics/tests/getAttributeType.test.ts b/src/frontend/statistics/tests/getAttributeType.test.ts
deleted file mode 100644
index 6b8923c..0000000
--- a/src/frontend/statistics/tests/getAttributeType.test.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { describe, it, expect } from 'bun:test';
-import { getAttributeType } from '../utils/getAttributeType';
-
-// Sample values for testing
-const invalidDate = '2023-13-03';
-const validTime = '12:30:45';
-const invalidTime = '25:61:61';
-const invalidDatetime = '2023-10-03 25:61:61';
-const validNumber = '123.45';
-const invalidNumber = 'abc123';
-const booleanTrue = true;
-const booleanFalse = false;
-const numberValue = 123;
-const arrayValue = [1, 2, 3];
-const objectValue = { key: 'value' };
-const dateInstance = new Date('2023-10-03T12:30:45');
-
-// Unit tests for getAttributeType function
-describe('getAttributeType', () => {
-  it('should correctly identify numbers as type "number"', () => {
-    expect(getAttributeType(validNumber)).toBe('number');
-    expect(getAttributeType(numberValue)).toBe('number');
-  });
-
-  it('should correctly identify strings as valid "time"', () => {
-    expect(getAttributeType(validTime)).toBe('time');
-  });
-
-  it('should identify invalid datetime strings as "string"', () => {
-    expect(getAttributeType(invalidDatetime)).toBe('string');
-  });
-
-  it('should identify invalid date strings as "string"', () => {
-    expect(getAttributeType(invalidDate)).toBe('string');
-  });
-
-  it('should identify invalid time strings as "string"', () => {
-    expect(getAttributeType(invalidTime)).toBe('string');
-  });
-
-  it('should correctly identify boolean values as type "boolean"', () => {
-    expect(getAttributeType(booleanTrue)).toBe('boolean');
-    expect(getAttributeType(booleanFalse)).toBe('boolean');
-  });
-
-  it('should correctly identify arrays as type "array"', () => {
-    expect(getAttributeType(arrayValue)).toBe('array');
-  });
-
-  it('should correctly identify objects as type "object"', () => {
-    expect(getAttributeType(objectValue)).toBe('object');
-  });
-
-  it('should correctly identify Date instances as type "datetime"', () => {
-    expect(getAttributeType(dateInstance)).toBe('datetime');
-  });
-
-  it('should identify string representations of invalid numbers as "string"', () => {
-    expect(getAttributeType(invalidNumber)).toBe('string');
-  });
-
-  it('should identify a regular string as type "string"', () => {
-    expect(getAttributeType('random string')).toBe('string');
-  });
-});
diff --git a/src/frontend/statistics/tests/graphStatistics.test.ts b/src/frontend/statistics/tests/graphStatistics.test.ts
deleted file mode 100644
index f2b912e..0000000
--- a/src/frontend/statistics/tests/graphStatistics.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import { describe, it, expect } from 'bun:test';
-import { getGraphStatistics } from '../graphStatistics';
-import type { GraphQueryResultFromBackend } from 'ts-common';
-
-describe('getGraphStatistics', () => {
-  it('should return correct statistics for a graph with no nodes and edges', () => {
-    const graph: GraphQueryResultFromBackend = {
-      nodes: [],
-      edges: [],
-    };
-
-    const stats = getGraphStatistics(graph);
-
-    expect(stats).toEqual({
-      topological: { density: 0, self_loops: 0 },
-      nodes: { labels: [], count: 0, types: {} },
-      edges: { labels: [], count: 0, types: {} },
-    });
-  });
-
-  it('should return correct statistics for a graph with nodes and no edges', () => {
-    const graph: GraphQueryResultFromBackend = {
-      nodes: [
-        { _id: '1', label: 'Person', attributes: { age: 25 } },
-        { _id: '2', label: 'Person', attributes: { age: 30, city: 'New York' } },
-      ],
-      edges: [],
-    };
-
-    const stats = getGraphStatistics(graph);
-
-    expect(stats).toEqual({
-      topological: { density: 0, self_loops: 0 },
-      nodes: {
-        labels: ['Person'], // Assuming default label
-        count: 2,
-        types: {
-          Person: {
-            count: 2,
-            attributes: {
-              age: { attributeType: 'number', statistics: expect.any(Object) },
-              city: { attributeType: 'string', statistics: expect.any(Object) },
-            },
-          },
-        },
-      },
-      edges: { labels: [], count: 0, types: {} },
-    });
-  });
-
-  it('should return correct statistics for a graph with edges and nodes', () => {
-    const graph: GraphQueryResultFromBackend = {
-      nodes: [
-        { _id: '1', label: 'Person', attributes: { age: 25 } },
-        { _id: '2', label: 'Person', attributes: { age: 30 } },
-      ],
-      edges: [
-        { _id: 'e1', label: 'Relationship', attributes: { weight: 5 }, from: '1', to: '2' },
-        { _id: 'e2', label: 'Relationship', attributes: { weight: 10 }, from: '2', to: '2' }, // self-loop
-      ],
-    };
-
-    const stats = getGraphStatistics(graph);
-
-    expect(stats).toEqual({
-      topological: { density: 2, self_loops: 1 },
-      nodes: {
-        labels: ['Person'], // Assuming default label
-        count: 2,
-        types: {
-          Person: {
-            count: 2,
-            attributes: {
-              age: { attributeType: 'number', statistics: expect.any(Object) },
-            },
-          },
-        },
-      },
-      edges: {
-        labels: ['Relationship'], // Assuming default edge type
-        count: 2,
-        types: {
-          Relationship: {
-            count: 2,
-            attributes: {
-              weight: { attributeType: 'number', statistics: expect.any(Object) },
-            },
-          },
-        },
-      },
-    });
-  });
-
-  it('should correctly count self-loops', () => {
-    const graph: GraphQueryResultFromBackend = {
-      nodes: [{ _id: '1', attributes: {}, label: 'Person' }],
-      edges: [
-        { _id: 'e1', attributes: {}, from: '1', to: '1', label: 'TO_PERSON' }, // self-loop
-      ],
-    };
-
-    const stats = getGraphStatistics(graph);
-
-    expect(stats.topological.self_loops).toBe(1);
-  });
-
-  it('should correctly compute density for a graph with nodes and edges', () => {
-    const graph: GraphQueryResultFromBackend = {
-      nodes: [
-        { _id: '1', attributes: {}, label: 'Person' },
-        { _id: '2', attributes: {}, label: 'Person' },
-      ],
-      edges: [{ _id: 'e1', attributes: {}, from: '1', to: '2', label: 'TO_PERSON' }],
-    };
-
-    const stats = getGraphStatistics(graph);
-
-    // Density = (n_edges * 2) / (n_nodes * (n_nodes - 1)) = (1 * 2) / (2 * 1) = 1
-    expect(stats.topological.density).toBe(1);
-  });
-});
diff --git a/src/frontend/statistics/utils/attributeStats/array.ts b/src/frontend/statistics/utils/attributeStats/array.ts
deleted file mode 100644
index 1845238..0000000
--- a/src/frontend/statistics/utils/attributeStats/array.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import type { ArrayStats } from 'ts-common';
-
-export const updateArrayStats = (stats: ArrayStats, value: any[]) => {
-  stats.length = value.length;
-  stats.count++;
-};
diff --git a/src/frontend/statistics/utils/attributeStats/boolean.ts b/src/frontend/statistics/utils/attributeStats/boolean.ts
deleted file mode 100644
index a737e97..0000000
--- a/src/frontend/statistics/utils/attributeStats/boolean.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { BooleanStats } from 'ts-common';
-
-export const updateBooleanStats = (stats: BooleanStats, value: boolean) => {
-  if (value) {
-    stats.true += 1;
-  } else {
-    stats.false += 1;
-  }
-};
diff --git a/src/frontend/statistics/utils/attributeStats/categorical.ts b/src/frontend/statistics/utils/attributeStats/categorical.ts
deleted file mode 100644
index 860cda7..0000000
--- a/src/frontend/statistics/utils/attributeStats/categorical.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import type { CategoricalStats } from 'ts-common';
-
-export const updateCategoricalStats = (stats: CategoricalStats, value: string | boolean) => {
-  if (!stats.values) stats.values = [];
-  stats.values.push(value.toString());
-
-  stats.uniqueItems = new Set(stats.values).size;
-
-  const frequencyMap: { [key: string]: number } = {};
-  stats.values.forEach(val => {
-    frequencyMap[val] = (frequencyMap[val] || 0) + 1;
-  });
-  stats.mode = Object.keys(frequencyMap).reduce((a, b) => (frequencyMap[a] > frequencyMap[b] ? a : b));
-  stats.count++;
-};
diff --git a/src/frontend/statistics/utils/attributeStats/index.ts b/src/frontend/statistics/utils/attributeStats/index.ts
deleted file mode 100644
index 42c4501..0000000
--- a/src/frontend/statistics/utils/attributeStats/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export * from './array';
-export * from './categorical';
-export * from './numerical';
-export * from './object';
-export * from './temporal';
-export * from './boolean';
-export * from './initialize';
diff --git a/src/frontend/statistics/utils/attributeStats/initialize.ts b/src/frontend/statistics/utils/attributeStats/initialize.ts
deleted file mode 100644
index d4431b4..0000000
--- a/src/frontend/statistics/utils/attributeStats/initialize.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { AttributeType, AttributeTypeStats } from 'ts-common';
-
-const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeStats<T> => {
-  switch (type) {
-    case 'string':
-      return {
-        uniqueItems: 0,
-        values: [],
-        mode: '',
-        count: 0,
-      } as unknown as AttributeTypeStats<T>;
-    case 'boolean':
-      return {
-        true: 0,
-        false: 0,
-      } as unknown as AttributeTypeStats<T>;
-    case 'number':
-      return {
-        min: Infinity,
-        max: -Infinity,
-        average: 0,
-        count: 0,
-      } as unknown as AttributeTypeStats<T>;
-    case 'date':
-    case 'time':
-    case 'datetime':
-    case 'timestamp':
-      return {
-        min: Infinity,
-        max: -Infinity,
-        range: 0,
-      } as unknown as AttributeTypeStats<T>;
-    case 'array':
-      return {
-        length: 0,
-        count: 0,
-      } as unknown as AttributeTypeStats<T>;
-    case 'object':
-      return {
-        length: 0,
-      } as unknown as AttributeTypeStats<T>;
-    default:
-      throw new Error(`Unknown attribute type: ${type}`);
-  }
-};
-
-export { initializeStatistics };
diff --git a/src/frontend/statistics/utils/attributeStats/numerical.ts b/src/frontend/statistics/utils/attributeStats/numerical.ts
deleted file mode 100644
index d0a68b5..0000000
--- a/src/frontend/statistics/utils/attributeStats/numerical.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { NumericalStats } from 'ts-common';
-
-export const updateNumericalStats = (stats: NumericalStats, value: number) => {
-  if (stats.min === undefined || value < stats.min) stats.min = value;
-  if (stats.max === undefined || value > stats.max) stats.max = value;
-
-  stats.count++;
-  stats.average = (stats.average * (stats.count - 1) + value) / stats.count;
-};
diff --git a/src/frontend/statistics/utils/attributeStats/object.ts b/src/frontend/statistics/utils/attributeStats/object.ts
deleted file mode 100644
index 46e60f2..0000000
--- a/src/frontend/statistics/utils/attributeStats/object.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { ObjectStats } from 'ts-common';
-
-export const updateObjectStats = (stats: ObjectStats, value: object) => {
-  stats.length = Object.keys(value).length;
-};
diff --git a/src/frontend/statistics/utils/attributeStats/temporal.ts b/src/frontend/statistics/utils/attributeStats/temporal.ts
deleted file mode 100644
index 49e1b3e..0000000
--- a/src/frontend/statistics/utils/attributeStats/temporal.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { TemporalStats } from 'ts-common';
-
-export const updateTemporalStats = (stats: TemporalStats, value: string | Date) => {
-  const timestamp = value instanceof Date ? value.getTime() : new Date(value).getTime();
-
-  if (stats.min === undefined || timestamp < stats.min) stats.min = timestamp;
-  if (stats.max === undefined || timestamp > stats.max) stats.max = timestamp;
-
-  stats.range = stats.max - stats.min;
-};
diff --git a/src/frontend/statistics/utils/getAttributeType.ts b/src/frontend/statistics/utils/getAttributeType.ts
deleted file mode 100644
index bb3f968..0000000
--- a/src/frontend/statistics/utils/getAttributeType.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import type { AttributeType } from 'ts-common';
-
-// Check if a string is a valid date in the YYYY-MM-DD format
-const isValidDate = (value: string): boolean => {
-  const dateRegex = /^\d{4}-\d{2}-\d{2}$/; // Matches YYYY-MM-DD format
-  const [year, month, day] = value.split('-').map(Number);
-  const date = new Date(value);
-
-  // Check if the regex matches, and if the date is valid (correct month/day conversion)
-  return (
-    dateRegex.test(value) &&
-    date.getFullYear() === year &&
-    date.getMonth() + 1 === month && // Months are 0-based in JS Date
-    date.getDate() === day
-  );
-};
-
-// Check if a string is a valid time in the hh:mm:ss format
-const isValidTime = (value: string): boolean => {
-  const timeRegex = /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/;
-  return timeRegex.test(value);
-};
-
-// Check if a string is a valid datetime in the YYYY-MM-DD hh:mm:ss format
-const isValidDatetime = (value: string): boolean => {
-  const datetimeRegex = /^\d{4}-\d{2}-\d{2} ([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/;
-  const [date, time] = value.split(' ');
-
-  return datetimeRegex.test(value) && isValidDate(date) && isValidTime(time);
-};
-
-// Check if a string is a valid number
-const isValidNumber = (value: string): boolean => {
-  return !isNaN(Number(value)) && !isNaN(parseFloat(value));
-};
-
-// Determines the type of an attribute
-const getAttributeType = (value: any): AttributeType => {
-  if (typeof value === 'string') {
-    if (isValidNumber(value)) {
-      return 'number';
-    }
-    if (isValidDatetime(value)) {
-      return 'datetime';
-    }
-    if (isValidDate(value)) {
-      return 'date';
-    }
-    if (isValidTime(value)) {
-      return 'time';
-    }
-    return 'string';
-  }
-
-  if (typeof value === 'boolean') {
-    return 'boolean';
-  }
-
-  if (typeof value === 'number') {
-    return 'number';
-  }
-
-  if (Array.isArray(value)) {
-    return 'array';
-  }
-
-  if (value instanceof Date) {
-    return 'datetime';
-  }
-
-  if (typeof value === 'object' && value !== null) {
-    return 'object';
-  }
-
-  return 'string';
-};
-
-export { getAttributeType };
diff --git a/src/frontend/statistics/utils/index.ts b/src/frontend/statistics/utils/index.ts
deleted file mode 100644
index 4fb895d..0000000
--- a/src/frontend/statistics/utils/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './getAttributeType';
-export * from './attributeStats';
-export * from './updateStatistics';
diff --git a/src/frontend/statistics/utils/updateStatistics.ts b/src/frontend/statistics/utils/updateStatistics.ts
deleted file mode 100644
index 03a49de..0000000
--- a/src/frontend/statistics/utils/updateStatistics.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import type {
-  ArrayStats,
-  AttributeStats,
-  AttributeType,
-  BooleanStats,
-  CategoricalStats,
-  NumericalStats,
-  ObjectStats,
-  TemporalStats,
-} from 'ts-common';
-import {
-  updateArrayStats,
-  updateCategoricalStats,
-  updateNumericalStats,
-  updateObjectStats,
-  updateTemporalStats,
-  updateBooleanStats,
-} from './attributeStats';
-
-// Update statistics based on attribute type and value
-export const updateStatistics = (attribute: AttributeStats<AttributeType>, value: any) => {
-  switch (attribute.attributeType) {
-    case 'number':
-      updateNumericalStats(attribute.statistics as NumericalStats, value);
-      break;
-    case 'string':
-      updateCategoricalStats(attribute.statistics as CategoricalStats, value);
-      break;
-    case 'boolean':
-      updateBooleanStats(attribute.statistics as BooleanStats, value);
-      break;
-    case 'datetime':
-    case 'timestamp':
-    case 'date':
-    case 'time':
-      updateTemporalStats(attribute.statistics as TemporalStats, value);
-      break;
-    case 'array':
-      updateArrayStats(attribute.statistics as ArrayStats, value);
-      break;
-    case 'object':
-      updateObjectStats(attribute.statistics as ObjectStats, value);
-      break;
-  }
-};
diff --git a/src/readers/queryService.ts b/src/readers/queryService.ts
index 5fa9526..448459b 100644
--- a/src/readers/queryService.ts
+++ b/src/readers/queryService.ts
@@ -1,4 +1,4 @@
-import { type DbConnection, type QueryRequest } from 'ts-common';
+import { graphQueryBackend2graphQuery, type DbConnection, type QueryRequest } from 'ts-common';
 
 import { rabbitMq, redis, ums, type QueryExecutionTypes } from '../variables';
 import { log } from '../logger';
@@ -6,11 +6,9 @@ import { QueryPublisher } from '../utils/queryPublisher';
 import { query2Cypher } from '../utils/cypher/converter';
 import { parseCypherQuery } from '../utils/cypher/queryParser';
 import { formatTimeDifference } from 'ts-common/src/logger/logger';
-import { graphQueryBackend2graphQuery } from '../frontend/statistics';
 import { Query2BackendQuery } from '../utils/reactflow/query2backend';
-import type { GraphQueryResultMetaFromBackend } from 'ts-common/src/model/webSocket/graphResult';
+import type { GraphQueryResultFromBackend, GraphQueryResultMetaFromBackend } from 'ts-common/src/model/webSocket/graphResult';
 import { RabbitMqBroker } from 'ts-common/rabbitMq';
-import { RedisConnector } from 'ts-common/redis';
 import { Neo4jConnection } from 'ts-common/neo4j';
 
 export const queryService = async (db: DbConnection, query: string): Promise<GraphQueryResultMetaFromBackend> => {
-- 
GitLab