From d9bd5adeb1c40698d9d32ccda1141629392ca8bf Mon Sep 17 00:00:00 2001 From: Nicola Krumschmidt Date: Fri, 17 Nov 2023 20:41:25 +0100 Subject: [PATCH] Refactor the file structure in data-sql (#20433) * Refactor data-sql types file structure * used types dir directly * target conversion outside of conditions, file for filter conversion result * type import only via index file * removed unused index files * Refactor data-sql types file structure * used types dir directly * target conversion outside of conditions, file for filter conversion result * type import only via index file * removed unused index files * fixed tests * rename --------- Co-authored-by: Jan Arends --- .../data-sql/src/query-converter/converter.ts | 3 +- .../fields/create-join.test.ts | 6 +- .../fields/create-nested-manys.ts | 2 +- .../src/query-converter/functions.test.ts | 6 +- .../modifiers/filter/conditions/conditions.ts | 2 +- .../modifiers/filter/conditions/field.test.ts | 2 +- .../modifiers/filter/conditions/field.ts | 4 +- .../modifiers/filter/conditions/geo.test.ts | 2 +- .../modifiers/filter/conditions/geo.ts | 4 +- .../filter/conditions/number.test.ts | 2 +- .../modifiers/filter/conditions/number.ts | 4 +- .../modifiers/filter/conditions/set.test.ts | 2 +- .../modifiers/filter/conditions/set.ts | 4 +- .../filter/conditions/string.test.ts | 2 +- .../modifiers/filter/conditions/string.ts | 4 +- .../modifiers/filter/filter.ts | 7 +-- .../query-converter/modifiers/filter/index.ts | 2 - .../modifiers/filter/logical.ts | 4 +- .../query-converter/modifiers/filter/utils.ts | 6 ++ .../src/query-converter/modifiers/index.ts | 2 - .../query-converter/modifiers/sort.test.ts | 4 +- .../src/query-converter/modifiers/sort.ts | 2 +- .../utils.test.ts => target.test.ts} | 6 +- .../{filter/conditions/utils.ts => target.ts} | 31 ++------- packages/data-sql/src/types/abstract-sql.ts | 60 ++++++++++++++++++ packages/data-sql/src/types/clauses.ts | 16 +++++ packages/data-sql/src/types/clauses/index.ts | 27 ++------ .../src/types/clauses/{joins => }/join.ts | 3 +- packages/data-sql/src/types/clauses/order.ts | 3 +- .../src/types/clauses/select/column.ts | 4 ++ .../types/clauses/{selects => select}/fn.ts | 4 +- .../src/types/clauses/select/index.ts | 4 ++ .../types/clauses/{selects => select}/json.ts | 0 .../clauses/{selects => select}/primitive.ts | 5 +- packages/data-sql/src/types/clauses/where.ts | 4 ++ .../src/types/clauses/where/condition.ts | 21 +++++++ .../where/conditions/field-condition.ts | 4 +- .../clauses/where/conditions/geo-condition.ts | 4 +- .../types/clauses/where/conditions/index.ts | 31 +-------- .../where/conditions/number-condition.ts | 4 +- .../clauses/where/conditions/set-condition.ts | 4 +- .../where/conditions/string-condition.ts | 4 +- .../data-sql/src/types/clauses/where/index.ts | 1 + .../src/types/clauses/where/logical.ts | 2 +- packages/data-sql/src/types/index.ts | 63 +------------------ 45 files changed, 179 insertions(+), 202 deletions(-) delete mode 100644 packages/data-sql/src/query-converter/modifiers/filter/index.ts create mode 100644 packages/data-sql/src/query-converter/modifiers/filter/utils.ts delete mode 100644 packages/data-sql/src/query-converter/modifiers/index.ts rename packages/data-sql/src/query-converter/modifiers/{filter/conditions/utils.test.ts => target.test.ts} (95%) rename packages/data-sql/src/query-converter/modifiers/{filter/conditions/utils.ts => target.ts} (70%) create mode 100644 packages/data-sql/src/types/abstract-sql.ts create mode 100644 packages/data-sql/src/types/clauses.ts rename packages/data-sql/src/types/clauses/{joins => }/join.ts (83%) create mode 100644 packages/data-sql/src/types/clauses/select/column.ts rename packages/data-sql/src/types/clauses/{selects => select}/fn.ts (84%) create mode 100644 packages/data-sql/src/types/clauses/select/index.ts rename packages/data-sql/src/types/clauses/{selects => select}/json.ts (100%) rename packages/data-sql/src/types/clauses/{selects => select}/primitive.ts (81%) create mode 100644 packages/data-sql/src/types/clauses/where.ts create mode 100644 packages/data-sql/src/types/clauses/where/condition.ts diff --git a/packages/data-sql/src/query-converter/converter.ts b/packages/data-sql/src/query-converter/converter.ts index 4b2a8a748a..3b72a1773d 100644 --- a/packages/data-sql/src/query-converter/converter.ts +++ b/packages/data-sql/src/query-converter/converter.ts @@ -5,8 +5,7 @@ * @module */ import type { AbstractQuery } from '@directus/data'; -import type { AbstractSqlClauses, AbstractSqlQuery } from '../types/index.js'; -import type { ParameterTypes } from '../types/parameterized-statement.js'; +import type { AbstractSqlClauses, AbstractSqlQuery, ParameterTypes } from '../types/index.js'; import { parameterIndexGenerator } from './param-index-generator.js'; import { convertFieldNodes } from './fields/index.js'; import { convertModifiers } from './modifiers/modifiers.js'; diff --git a/packages/data-sql/src/query-converter/fields/create-join.test.ts b/packages/data-sql/src/query-converter/fields/create-join.test.ts index a4a6d3d6fa..add3315cbe 100644 --- a/packages/data-sql/src/query-converter/fields/create-join.test.ts +++ b/packages/data-sql/src/query-converter/fields/create-join.test.ts @@ -1,8 +1,8 @@ -import { expect, test } from 'vitest'; -import { randomIdentifier } from '@directus/random'; import type { AbstractQueryFieldNodeRelationalManyToOne } from '@directus/data'; +import { randomIdentifier } from '@directus/random'; +import { expect, test } from 'vitest'; +import type { AbstractSqlQueryJoinNode } from '../../types/index.js'; import { createJoin } from './create-join.js'; -import type { AbstractSqlQueryJoinNode } from '../../types/clauses/joins/join.js'; test('Convert m2o relation on single field ', () => { const randomCurrentCollection = randomIdentifier(); diff --git a/packages/data-sql/src/query-converter/fields/create-nested-manys.ts b/packages/data-sql/src/query-converter/fields/create-nested-manys.ts index 5aefbd61c1..dc0d79610d 100644 --- a/packages/data-sql/src/query-converter/fields/create-nested-manys.ts +++ b/packages/data-sql/src/query-converter/fields/create-nested-manys.ts @@ -8,7 +8,7 @@ import type { AbstractSqlNestedMany, AbstractSqlQueryConditionNode, AbstractSqlQueryWhereNode, -} from '../../index.js'; +} from '../../types/index.js'; import { convertModifiers } from '../modifiers/modifiers.js'; import { parameterIndexGenerator } from '../param-index-generator.js'; import { convertFieldNodes } from './fields.js'; diff --git a/packages/data-sql/src/query-converter/functions.test.ts b/packages/data-sql/src/query-converter/functions.test.ts index fab70cb737..c118e710e7 100644 --- a/packages/data-sql/src/query-converter/functions.test.ts +++ b/packages/data-sql/src/query-converter/functions.test.ts @@ -1,9 +1,9 @@ import type { AbstractQueryFunction } from '@directus/data'; import { randomAlpha, randomIdentifier } from '@directus/random'; -import { describe, expect, test, beforeEach } from 'vitest'; -import type { AbstractSqlQueryFnNode } from '../types/clauses/selects/fn.js'; -import { parameterIndexGenerator } from './param-index-generator.js'; +import { beforeEach, describe, expect, test } from 'vitest'; +import type { AbstractSqlQueryFnNode } from '../types/index.js'; import { convertFn } from './functions.js'; +import { parameterIndexGenerator } from './param-index-generator.js'; let randomCollection: string; let idGen: Generator; diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/conditions.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/conditions.ts index 6755f9608e..697fa801ab 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/conditions.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/conditions.ts @@ -4,7 +4,7 @@ import { convertGeoCondition } from './geo.js'; import { convertStringNode } from './string.js'; import { convertNumberNode } from './number.js'; import { convertSetCondition } from './set.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; /** * Forward the condition to the correct converter. diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.test.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.test.ts index 8e3bd4a2e8..5a59bce739 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.test.ts @@ -2,7 +2,7 @@ import type { ConditionFieldNode } from '@directus/data'; import { randomIdentifier } from '@directus/random'; import { expect, test } from 'vitest'; import { parameterIndexGenerator } from '../../../param-index-generator.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; import { convertFieldCondition } from './field.js'; test('convert field condition', () => { diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.ts index fac8b1c2db..cfa7901193 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/field.ts @@ -1,6 +1,6 @@ import type { ConditionFieldNode } from '@directus/data'; -import type { FilterResult } from '../filter.js'; -import { convertTarget } from './utils.js'; +import type { FilterResult } from '../utils.js'; +import { convertTarget } from '../../target.js'; export function convertFieldCondition( node: ConditionFieldNode, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.test.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.test.ts index 1303eaa5e7..5f964b4c89 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.test.ts @@ -5,7 +5,7 @@ import type { GeoJSONGeometry } from 'wellknown'; import type { AbstractSqlQueryConditionNode } from '../../../../types/clauses/where/index.js'; import { parameterIndexGenerator } from '../../../param-index-generator.js'; import { convertGeoCondition } from './geo.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; test('convert geo condition', () => { const idGen = parameterIndexGenerator(); diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.ts index 6ba44b1989..6a1b26abce 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/geo.ts @@ -1,6 +1,6 @@ import type { ConditionGeoIntersectsNode, ConditionGeoIntersectsBBoxNode } from '@directus/data'; -import { convertTarget } from './utils.js'; -import type { FilterResult } from '../filter.js'; +import { convertTarget } from '../../target.js'; +import type { FilterResult } from '../utils.js'; export function convertGeoCondition( node: ConditionGeoIntersectsNode | ConditionGeoIntersectsBBoxNode, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.test.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.test.ts index 0866dc2ff1..453801ec3b 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.test.ts @@ -4,7 +4,7 @@ import { expect, test, beforeEach } from 'vitest'; import { parameterIndexGenerator } from '../../../param-index-generator.js'; import { convertNumberNode } from './number.js'; import type { AbstractSqlQueryConditionNode } from '../../../../index.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; let idGen: Generator; let randomCollection: string; diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.ts index f512ac2fd6..44d9c7be6a 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/number.ts @@ -1,6 +1,6 @@ import type { ConditionNumberNode } from '@directus/data'; -import { convertTarget } from './utils.js'; -import type { FilterResult } from '../filter.js'; +import { convertTarget } from '../../target.js'; +import type { FilterResult } from '../utils.js'; export function convertNumberNode( node: ConditionNumberNode, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.test.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.test.ts index 6b733f66d3..6ba08d94e1 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.test.ts @@ -4,7 +4,7 @@ import { expect, test } from 'vitest'; import type { AbstractSqlQueryConditionNode } from '../../../../types/clauses/where/index.js'; import { parameterIndexGenerator } from '../../../param-index-generator.js'; import { convertSetCondition } from './set.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; test('convert set condition', () => { const idGen = parameterIndexGenerator(); diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.ts index 2ce2b03c0a..ecacd02325 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/set.ts @@ -1,6 +1,6 @@ import type { ConditionSetNode } from '@directus/data'; -import { convertTarget } from './utils.js'; -import type { FilterResult } from '../filter.js'; +import { convertTarget } from '../../target.js'; +import type { FilterResult } from '../utils.js'; export function convertSetCondition( node: ConditionSetNode, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.test.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.test.ts index 7dfcc1e854..b361c1fbf5 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.test.ts @@ -4,7 +4,7 @@ import { expect, test } from 'vitest'; import { parameterIndexGenerator } from '../../../param-index-generator.js'; import { convertStringNode } from './string.js'; import type { AbstractSqlQueryConditionNode } from '../../../../types/index.js'; -import type { FilterResult } from '../filter.js'; +import type { FilterResult } from '../utils.js'; test('convert string condition', () => { const idGen = parameterIndexGenerator(); diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.ts b/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.ts index 99069c7b80..2d4f9956f2 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/conditions/string.ts @@ -1,6 +1,6 @@ import type { ConditionStringNode } from '@directus/data'; -import { convertTarget } from './utils.js'; -import type { FilterResult } from '../filter.js'; +import { convertTarget } from '../../target.js'; +import type { FilterResult } from '../utils.js'; export function convertStringNode( node: ConditionStringNode, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/filter.ts b/packages/data-sql/src/query-converter/modifiers/filter/filter.ts index 07b0168b35..94c577145b 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/filter.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/filter.ts @@ -1,12 +1,7 @@ import type { AbstractQueryConditionNode, AbstractQueryFilterNode, AtLeastOneElement } from '@directus/data'; -import type { AbstractSqlClauses, AbstractSqlQuery } from '../../../types/index.js'; import { convertCondition } from './conditions/conditions.js'; import { convertLogical } from './logical.js'; - -export type FilterResult = { - clauses: Required>; - parameters: AbstractSqlQuery['parameters']; -}; +import type { FilterResult } from './utils.js'; /** * Extracts the user provided filter values and puts them in the list of parameters. diff --git a/packages/data-sql/src/query-converter/modifiers/filter/index.ts b/packages/data-sql/src/query-converter/modifiers/filter/index.ts deleted file mode 100644 index 4cd823c440..0000000000 --- a/packages/data-sql/src/query-converter/modifiers/filter/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './logical.js'; -export * from './filter.js'; diff --git a/packages/data-sql/src/query-converter/modifiers/filter/logical.ts b/packages/data-sql/src/query-converter/modifiers/filter/logical.ts index 919dba8eb0..bd9ec7351c 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/logical.ts +++ b/packages/data-sql/src/query-converter/modifiers/filter/logical.ts @@ -1,6 +1,6 @@ import type { AtLeastOneElement } from '@directus/data'; -import type { AbstractSqlQueryWhereNode } from '../../../index.js'; -import type { FilterResult } from './filter.js'; +import type { AbstractSqlQueryWhereNode } from '../../../types/index.js'; +import type { FilterResult } from './utils.js'; export function convertLogical( children: AtLeastOneElement, diff --git a/packages/data-sql/src/query-converter/modifiers/filter/utils.ts b/packages/data-sql/src/query-converter/modifiers/filter/utils.ts new file mode 100644 index 0000000000..7769d0cebb --- /dev/null +++ b/packages/data-sql/src/query-converter/modifiers/filter/utils.ts @@ -0,0 +1,6 @@ +import type { AbstractSqlClauses, AbstractSqlQuery } from '../../../types/index.js'; + +export type FilterResult = { + clauses: Required>; + parameters: AbstractSqlQuery['parameters']; +}; diff --git a/packages/data-sql/src/query-converter/modifiers/index.ts b/packages/data-sql/src/query-converter/modifiers/index.ts deleted file mode 100644 index b11a1ec7aa..0000000000 --- a/packages/data-sql/src/query-converter/modifiers/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './filter/index.js'; -export * from './sort.js'; diff --git a/packages/data-sql/src/query-converter/modifiers/sort.test.ts b/packages/data-sql/src/query-converter/modifiers/sort.test.ts index 9fb249d45c..397fcea345 100644 --- a/packages/data-sql/src/query-converter/modifiers/sort.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/sort.test.ts @@ -3,10 +3,10 @@ import { beforeEach, expect, test, vi } from 'vitest'; import { randomIdentifier } from '@directus/random'; import { convertSort, type SortConversionResult } from './sort.js'; import { parameterIndexGenerator } from '../param-index-generator.js'; -import { convertTarget, type TargetConversionResult } from './filter/conditions/utils.js'; +import { convertTarget, type TargetConversionResult } from './target.js'; import type { AbstractSqlQuerySelectNode } from '../../index.js'; -vi.mock('./filter/conditions/utils.js', (importOriginal) => { +vi.mock('./target.js', (importOriginal) => { const original = importOriginal(); return { ...original, diff --git a/packages/data-sql/src/query-converter/modifiers/sort.ts b/packages/data-sql/src/query-converter/modifiers/sort.ts index 2f608d79f0..47727d1b29 100644 --- a/packages/data-sql/src/query-converter/modifiers/sort.ts +++ b/packages/data-sql/src/query-converter/modifiers/sort.ts @@ -1,6 +1,6 @@ import type { AbstractQueryNodeSort, AtLeastOneElement } from '@directus/data'; import type { AbstractSqlClauses, AbstractSqlQueryOrderNode } from '../../types/index.js'; -import { convertTarget } from './filter/conditions/utils.js'; +import { convertTarget } from './target.js'; export type SortConversionResult = { clauses: Required>; diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.test.ts b/packages/data-sql/src/query-converter/modifiers/target.test.ts similarity index 95% rename from packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.test.ts rename to packages/data-sql/src/query-converter/modifiers/target.test.ts index 9f06f43585..9a29c4e6d0 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.test.ts +++ b/packages/data-sql/src/query-converter/modifiers/target.test.ts @@ -1,10 +1,10 @@ import { expect, test, vi } from 'vitest'; -import { convertNestedOneTarget, convertTarget, type TargetConversionResult } from './utils.js'; +import { convertNestedOneTarget, convertTarget, type TargetConversionResult } from './target.js'; import type { AbstractQueryTargetNestedOne, ConditionNumberNode, ConditionStringNode } from '@directus/data'; -import { parameterIndexGenerator } from '../../../param-index-generator.js'; +import { parameterIndexGenerator } from '../param-index-generator.js'; import { randomIdentifier, randomInteger } from '@directus/random'; -vi.mock('../../../../orm/create-unique-alias.js', () => ({ +vi.mock('../../orm/create-unique-alias.js', () => ({ createUniqueAlias: vi.fn().mockImplementation((i) => `${i}_RANDOM`), })); diff --git a/packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.ts b/packages/data-sql/src/query-converter/modifiers/target.ts similarity index 70% rename from packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.ts rename to packages/data-sql/src/query-converter/modifiers/target.ts index 6dab329a1a..4835650373 100644 --- a/packages/data-sql/src/query-converter/modifiers/filter/conditions/utils.ts +++ b/packages/data-sql/src/query-converter/modifiers/target.ts @@ -1,33 +1,12 @@ -import type { - AbstractQueryFieldNodePrimitive, - AbstractQueryTarget, - AbstractQueryTargetNestedOne, -} from '@directus/data'; -import { createUniqueAlias } from '../../../../orm/create-unique-alias.js'; +import type { AbstractQueryTarget, AbstractQueryTargetNestedOne } from '@directus/data'; +import { createUniqueAlias } from '../../orm/create-unique-alias.js'; import type { AbstractSqlQueryFnNode, AbstractSqlQueryJoinNode, AbstractSqlQuerySelectNode, -} from '../../../../types/index.js'; -import { createJoin } from '../../../fields/create-join.js'; -import { convertFn } from '../../../functions.js'; - -/** - * It adds the table name to the node. - * @param collection - * @param primitiveNode - * @returns an unambitious column - */ -export function convertPrimitive( - collection: string, - primitiveNode: AbstractQueryFieldNodePrimitive -): AbstractSqlQuerySelectNode { - return { - type: 'primitive', - table: collection, - column: primitiveNode.field, - }; -} +} from '../../types/index.js'; +import { createJoin } from '../fields/create-join.js'; +import { convertFn } from '../functions.js'; export interface TargetConversionResult { value: AbstractSqlQuerySelectNode | AbstractSqlQueryFnNode; diff --git a/packages/data-sql/src/types/abstract-sql.ts b/packages/data-sql/src/types/abstract-sql.ts new file mode 100644 index 0000000000..47125145c8 --- /dev/null +++ b/packages/data-sql/src/types/abstract-sql.ts @@ -0,0 +1,60 @@ +/** + * A set of types which form the abstract SQL query. + * It's still neutral to concrete SQL dialects and databases but provides to SQL drivers with a query type that they can more easy work with. + * + * How the abstract SQL query types differ from the abstract query. + * - In the abstract query the user input values are put directly within the query directly. + * The abstract SQL however stores the user input values in a list of parameters, so that the SQL driver always perform parameterized queries. + * That way we prevent SQL injection. + * Moving the user input values into a list of parameters and replace the input value with the index of the value from the list, is a big part of the converter. + * - Instead of a wrapper for negation, here the negation is a property on the type. + * So the abstract SQL does not have a node of type 'negate' but instead the nodes have a property called 'negate'. + * + * @module + */ +import type { AtLeastOneElement } from '@directus/data'; +import type { AbstractSqlClauses } from './clauses.js'; +import type { ParameterTypes } from './parameterized-statement.js'; + +/** + * This is an abstract SQL query which can be passed to all SQL drivers. + * + * @example + * The following query gets the title of all articles and limits the result to 25 rows. + * ```ts + * const query: SqlStatement = { + * clauses: { + * select: [title], + * from: 'articles', + * limit: 0, // this is the index of the parameter + * }, + * parameters: [25], + * aliasMapping: ..., + * nestedMany: [], + * }; + * ``` + */ +export interface AbstractSqlQuery { + /* all clauses each and every driver will use */ + clauses: AbstractSqlClauses; + + /* the parameters which will be passed separately to the database for security reasons */ + parameters: ParameterTypes[]; + + /* a map from the generated, random alias to the actual path */ + aliasMapping: Map; + + /* how o2m relations are handled is driver specific and hence just forwarded */ + nestedManys: AbstractSqlNestedMany[]; +} + +export interface AbstractSqlNestedMany { + /* + * The nested many sub queries cannot be generated completely, since they rely on the result of the root query + * Therefore we use a function here instead, which takes the missing values as parameters to generate the actual sub query. + */ + queryGenerator: (joinFieldValues: AtLeastOneElement) => AbstractSqlQuery; + localJoinFields: AtLeastOneElement; + foreignJoinFields: AtLeastOneElement; + alias: string; +} diff --git a/packages/data-sql/src/types/clauses.ts b/packages/data-sql/src/types/clauses.ts new file mode 100644 index 0000000000..1cf561e832 --- /dev/null +++ b/packages/data-sql/src/types/clauses.ts @@ -0,0 +1,16 @@ +import type { AbstractSqlQueryJoinNode } from './clauses/join.js'; +import type { AbstractSqlQueryOrderNode } from './clauses/order.js'; +import type { AbstractSqlQueryFnNode } from './clauses/select/fn.js'; +import type { AbstractSqlQuerySelectNode } from './clauses/select/primitive.js'; +import type { AbstractSqlQueryWhereNode } from './clauses/where.js'; +import type { ValueNode } from './parameterized-statement.js'; + +export interface AbstractSqlClauses { + select: (AbstractSqlQuerySelectNode | AbstractSqlQueryFnNode)[]; + from: string; + joins?: AbstractSqlQueryJoinNode[]; + where?: AbstractSqlQueryWhereNode; + limit?: ValueNode; + offset?: ValueNode; + order?: AbstractSqlQueryOrderNode[]; +} diff --git a/packages/data-sql/src/types/clauses/index.ts b/packages/data-sql/src/types/clauses/index.ts index a0028d395f..8e894ff210 100644 --- a/packages/data-sql/src/types/clauses/index.ts +++ b/packages/data-sql/src/types/clauses/index.ts @@ -1,24 +1,5 @@ -import type { ValueNode } from '../parameterized-statement.js'; -import type { AbstractSqlQueryJoinNode } from './joins/join.js'; -import type { AbstractSqlQueryOrderNode } from './order.js'; -import type { AbstractSqlQueryFnNode } from './selects/fn.js'; -import type { AbstractSqlQuerySelectNode } from './selects/primitive.js'; -import type { AbstractSqlQueryConditionNode, AbstractSqlQueryLogicalNode } from './where/index.js'; - -export interface AbstractSqlClauses { - select: (AbstractSqlQuerySelectNode | AbstractSqlQueryFnNode)[]; - from: string; - joins?: AbstractSqlQueryJoinNode[]; - where?: AbstractSqlQueryWhereNode; - limit?: ValueNode; - offset?: ValueNode; - order?: AbstractSqlQueryOrderNode[]; -} - -export type AbstractSqlQueryWhereNode = AbstractSqlQueryConditionNode | AbstractSqlQueryLogicalNode; - -export * from './selects/fn.js'; -export * from './selects/primitive.js'; -export * from './joins/join.js'; -export * from './where/index.js'; +export * from './join.js'; export * from './order.js'; +export * from './select/index.js'; +export * from './where.js'; +export * from './where/index.js'; diff --git a/packages/data-sql/src/types/clauses/joins/join.ts b/packages/data-sql/src/types/clauses/join.ts similarity index 83% rename from packages/data-sql/src/types/clauses/joins/join.ts rename to packages/data-sql/src/types/clauses/join.ts index dc72d442d4..63477ec8b0 100644 --- a/packages/data-sql/src/types/clauses/joins/join.ts +++ b/packages/data-sql/src/types/clauses/join.ts @@ -1,4 +1,5 @@ -import type { AbstractSqlQueryLogicalNode, AbstractSqlQueryConditionNode } from '../where/index.js'; +import type { AbstractSqlQueryConditionNode } from './where/condition.js'; +import type { AbstractSqlQueryLogicalNode } from './where/logical.js'; /** * Used to join another table, regardless of the type of relation. diff --git a/packages/data-sql/src/types/clauses/order.ts b/packages/data-sql/src/types/clauses/order.ts index 054019db47..53afd118a0 100644 --- a/packages/data-sql/src/types/clauses/order.ts +++ b/packages/data-sql/src/types/clauses/order.ts @@ -1,4 +1,5 @@ -import type { AbstractSqlQueryFnNode, AbstractSqlQuerySelectNode } from './index.js'; +import type { AbstractSqlQueryFnNode } from './select/fn.js'; +import type { AbstractSqlQuerySelectNode } from './select/primitive.js'; export interface AbstractSqlQueryOrderNode { type: 'order'; diff --git a/packages/data-sql/src/types/clauses/select/column.ts b/packages/data-sql/src/types/clauses/select/column.ts new file mode 100644 index 0000000000..1aedbb01cd --- /dev/null +++ b/packages/data-sql/src/types/clauses/select/column.ts @@ -0,0 +1,4 @@ +export interface AbstractSqlQueryColumn { + table: string; + column: string; +} diff --git a/packages/data-sql/src/types/clauses/selects/fn.ts b/packages/data-sql/src/types/clauses/select/fn.ts similarity index 84% rename from packages/data-sql/src/types/clauses/selects/fn.ts rename to packages/data-sql/src/types/clauses/select/fn.ts index a0ea0a6a3b..42efe1c0c5 100644 --- a/packages/data-sql/src/types/clauses/selects/fn.ts +++ b/packages/data-sql/src/types/clauses/select/fn.ts @@ -1,6 +1,6 @@ -import type { AbstractSqlQueryColumn } from './primitive.js'; +import type { ArrayFn, ExtractFn } from '@directus/data'; import type { ValuesNode } from '../../parameterized-statement.js'; -import type { ExtractFn, ArrayFn } from '@directus/data'; +import type { AbstractSqlQueryColumn } from './column.js'; /** * Used to apply a function to a column. diff --git a/packages/data-sql/src/types/clauses/select/index.ts b/packages/data-sql/src/types/clauses/select/index.ts new file mode 100644 index 0000000000..f1d3b1f981 --- /dev/null +++ b/packages/data-sql/src/types/clauses/select/index.ts @@ -0,0 +1,4 @@ +export * from './column.js'; +export * from './fn.js'; +export * from './json.js'; +export * from './primitive.js'; diff --git a/packages/data-sql/src/types/clauses/selects/json.ts b/packages/data-sql/src/types/clauses/select/json.ts similarity index 100% rename from packages/data-sql/src/types/clauses/selects/json.ts rename to packages/data-sql/src/types/clauses/select/json.ts diff --git a/packages/data-sql/src/types/clauses/selects/primitive.ts b/packages/data-sql/src/types/clauses/select/primitive.ts similarity index 81% rename from packages/data-sql/src/types/clauses/selects/primitive.ts rename to packages/data-sql/src/types/clauses/select/primitive.ts index 3b839be78f..69aed0f76f 100644 --- a/packages/data-sql/src/types/clauses/selects/primitive.ts +++ b/packages/data-sql/src/types/clauses/select/primitive.ts @@ -1,7 +1,4 @@ -export interface AbstractSqlQueryColumn { - table: string; - column: string; -} +import type { AbstractSqlQueryColumn } from './column.js'; /** * Used to select a specific column from a table. diff --git a/packages/data-sql/src/types/clauses/where.ts b/packages/data-sql/src/types/clauses/where.ts new file mode 100644 index 0000000000..b2ced856ef --- /dev/null +++ b/packages/data-sql/src/types/clauses/where.ts @@ -0,0 +1,4 @@ +import type { AbstractSqlQueryConditionNode } from './where/condition.js'; +import type { AbstractSqlQueryLogicalNode } from './where/logical.js'; + +export type AbstractSqlQueryWhereNode = AbstractSqlQueryConditionNode | AbstractSqlQueryLogicalNode; diff --git a/packages/data-sql/src/types/clauses/where/condition.ts b/packages/data-sql/src/types/clauses/where/condition.ts new file mode 100644 index 0000000000..6b0c003cad --- /dev/null +++ b/packages/data-sql/src/types/clauses/where/condition.ts @@ -0,0 +1,21 @@ +import type { SqlConditionFieldNode } from './conditions/field-condition.js'; +import type { SqlConditionGeoNode } from './conditions/geo-condition.js'; +import type { SqlConditionNumberNode } from './conditions/number-condition.js'; +import type { SqlConditionSetNode } from './conditions/set-condition.js'; +import type { SqlConditionStringNode } from './conditions/string-condition.js'; + +/** + * Condition to filter rows. + * Various condition types are supported, each depending on a specific datatype. + * The condition can also be negated on this level. + */ +export interface AbstractSqlQueryConditionNode { + type: 'condition'; + condition: + | SqlConditionStringNode + | SqlConditionNumberNode + | SqlConditionGeoNode + | SqlConditionSetNode + | SqlConditionFieldNode; + negate: boolean; +} diff --git a/packages/data-sql/src/types/clauses/where/conditions/field-condition.ts b/packages/data-sql/src/types/clauses/where/conditions/field-condition.ts index f95c8d67d1..9405d7121b 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/field-condition.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/field-condition.ts @@ -1,5 +1,5 @@ -import type { AbstractSqlQueryFnNode } from '../../selects/fn.js'; -import type { AbstractSqlQuerySelectNode } from '../../selects/primitive.js'; +import type { AbstractSqlQueryFnNode } from '../../select/fn.js'; +import type { AbstractSqlQuerySelectNode } from '../../select/primitive.js'; /** * Condition to filter rows where two columns of different tables are equal. diff --git a/packages/data-sql/src/types/clauses/where/conditions/geo-condition.ts b/packages/data-sql/src/types/clauses/where/conditions/geo-condition.ts index dc45e6f1e7..88b7060c29 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/geo-condition.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/geo-condition.ts @@ -1,6 +1,6 @@ import type { ValueNode } from '../../../parameterized-statement.js'; -import type { AbstractSqlQueryFnNode } from '../../selects/fn.js'; -import type { AbstractSqlQuerySelectNode } from '../../selects/primitive.js'; +import type { AbstractSqlQueryFnNode } from '../../select/fn.js'; +import type { AbstractSqlQuerySelectNode } from '../../select/primitive.js'; /** * Used to retrieve a set of data, where the column in question stores a geographic value which intersects with another given geographic value. diff --git a/packages/data-sql/src/types/clauses/where/conditions/index.ts b/packages/data-sql/src/types/clauses/where/conditions/index.ts index 008c82c097..2695f7c0d9 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/index.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/index.ts @@ -1,34 +1,5 @@ -import type { SqlConditionFieldNode } from './field-condition.js'; -import type { SqlConditionGeoNode } from './geo-condition.js'; -import type { SqlConditionNumberNode } from './number-condition.js'; -import type { SqlConditionSetNode } from './set-condition.js'; -import type { SqlConditionStringNode } from './string-condition.js'; - -/** - * Condition to filter rows. - * Various condition types are supported, each depending on a specific datatype. - * The condition can also be negated on this level. - */ -export interface AbstractSqlQueryConditionNode { - type: 'condition'; - condition: - | SqlConditionStringNode - | SqlConditionNumberNode - | SqlConditionGeoNode - | SqlConditionSetNode - | SqlConditionFieldNode; - negate: boolean; -} - -export type SqlConditionType = - | 'condition-string' - | 'condition-number' - | 'condition-geo' - | 'condition-set' - | 'condition-field'; - export * from './field-condition.js'; export * from './geo-condition.js'; export * from './number-condition.js'; -export * from './string-condition.js'; export * from './set-condition.js'; +export * from './string-condition.js'; diff --git a/packages/data-sql/src/types/clauses/where/conditions/number-condition.ts b/packages/data-sql/src/types/clauses/where/conditions/number-condition.ts index c88306701b..0b39fcf6e5 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/number-condition.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/number-condition.ts @@ -1,6 +1,6 @@ -import type { AbstractSqlQueryFnNode } from '../../selects/fn.js'; +import type { AbstractSqlQueryFnNode } from '../../select/fn.js'; import type { ValueNode } from '../../../parameterized-statement.js'; -import type { AbstractSqlQuerySelectNode } from '../../selects/primitive.js'; +import type { AbstractSqlQuerySelectNode } from '../../select/primitive.js'; /** * Filter rows where a numeric column is equal, greater than, less than, etc. other given number. diff --git a/packages/data-sql/src/types/clauses/where/conditions/set-condition.ts b/packages/data-sql/src/types/clauses/where/conditions/set-condition.ts index 312fba7f20..60db10a9eb 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/set-condition.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/set-condition.ts @@ -1,6 +1,6 @@ import type { ValuesNode } from '../../../parameterized-statement.js'; -import type { AbstractSqlQueryFnNode } from '../../selects/fn.js'; -import type { AbstractSqlQuerySelectNode } from '../../selects/primitive.js'; +import type { AbstractSqlQueryFnNode } from '../../select/fn.js'; +import type { AbstractSqlQuerySelectNode } from '../../select/primitive.js'; /* * Condition to filter rows where a column value is in a list of values. diff --git a/packages/data-sql/src/types/clauses/where/conditions/string-condition.ts b/packages/data-sql/src/types/clauses/where/conditions/string-condition.ts index 881438757b..5a87c2c109 100644 --- a/packages/data-sql/src/types/clauses/where/conditions/string-condition.ts +++ b/packages/data-sql/src/types/clauses/where/conditions/string-condition.ts @@ -1,6 +1,6 @@ import type { ValueNode } from '../../../parameterized-statement.js'; -import type { AbstractSqlQueryFnNode } from '../../selects/fn.js'; -import type { AbstractSqlQuerySelectNode } from '../../selects/primitive.js'; +import type { AbstractSqlQueryFnNode } from '../../select/fn.js'; +import type { AbstractSqlQuerySelectNode } from '../../select/primitive.js'; /** * Condition to filter rows where a string column value contains, starts with, ends with, or is equal to another given string. diff --git a/packages/data-sql/src/types/clauses/where/index.ts b/packages/data-sql/src/types/clauses/where/index.ts index 6f2bb9ff20..25bb89c6de 100644 --- a/packages/data-sql/src/types/clauses/where/index.ts +++ b/packages/data-sql/src/types/clauses/where/index.ts @@ -1,2 +1,3 @@ +export * from './condition.js'; export * from './conditions/index.js'; export * from './logical.js'; diff --git a/packages/data-sql/src/types/clauses/where/logical.ts b/packages/data-sql/src/types/clauses/where/logical.ts index 007ffb2bfc..412ab8d452 100644 --- a/packages/data-sql/src/types/clauses/where/logical.ts +++ b/packages/data-sql/src/types/clauses/where/logical.ts @@ -1,5 +1,5 @@ import type { AtLeastOneElement } from '@directus/data'; -import type { AbstractSqlQueryConditionNode } from './conditions/index.js'; +import type { AbstractSqlQueryConditionNode } from './condition.js'; /** * A wrapper to add multiple conditions at once. diff --git a/packages/data-sql/src/types/index.ts b/packages/data-sql/src/types/index.ts index e0141027f5..4f412f936d 100644 --- a/packages/data-sql/src/types/index.ts +++ b/packages/data-sql/src/types/index.ts @@ -1,63 +1,4 @@ -/** - * A set of types which form the abstract SQL query. - * It's still neutral to concrete SQL dialects and databases but provides to SQL drivers with a query type that they can more easy work with. - * - * How the abstract SQL query types differ from the abstract query. - * - In the abstract query the user input values are put directly within the query directly. - * The abstract SQL however stores the user input values in a list of parameters, so that the SQL driver always perform parameterized queries. - * That way we prevent SQL injection. - * Moving the user input values into a list of parameters and replace the input value with the index of the value from the list, is a big part of the converter. - * - Instead of a wrapper for negation, here the negation is a property on the type. - * So the abstract SQL does not have a node of type 'negate' but instead the nodes have a property called 'negate'. - * - * @module - */ -import type { ParameterTypes } from './parameterized-statement.js'; -import type { AbstractSqlClauses } from './clauses/index.js'; -import type { AtLeastOneElement } from '@directus/data'; - -/** - * This is an abstract SQL query which can be passed to all SQL drivers. - * - * @example - * The following query gets the title of all articles and limits the result to 25 rows. - * ```ts - * const query: SqlStatement = { - * clauses: { - * select: [title], - * from: 'articles', - * limit: 0, // this is the index of the parameter - * }, - * parameters: [25], - * aliasMapping: ..., - * nestedMany: [], - * }; - * ``` - */ -export interface AbstractSqlQuery { - /* all clauses each and every driver will use */ - clauses: AbstractSqlClauses; - - /* the parameters which will be passed separately to the database for security reasons */ - parameters: ParameterTypes[]; - - /* a map from the generated, random alias to the actual path */ - aliasMapping: Map; - - /* how o2m relations are handled is driver specific and hence just forwarded */ - nestedManys: AbstractSqlNestedMany[]; -} - -export interface AbstractSqlNestedMany { - /* - * The nested many sub queries cannot be generated completely, since they rely on the result of the root query. - * Therefore we use a function here instead, which takes the missing values as parameters to generate the actual sub query. - */ - queryGenerator: (joinFieldValues: AtLeastOneElement) => AbstractSqlQuery; - localJoinFields: AtLeastOneElement; - foreignJoinFields: AtLeastOneElement; - alias: string; -} - +export * from './abstract-sql.js'; +export * from './clauses.js'; export * from './clauses/index.js'; export * from './parameterized-statement.js';