mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
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 <jan.arends@mailbox.org>
This commit is contained in:
committed by
GitHub
parent
985cef5eb5
commit
d9bd5adeb1
@@ -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';
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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<number, number, number>;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<number, number, number>;
|
||||
let randomCollection: string;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Pick<AbstractSqlClauses, 'where' | 'joins'>>;
|
||||
parameters: AbstractSqlQuery['parameters'];
|
||||
};
|
||||
import type { FilterResult } from './utils.js';
|
||||
|
||||
/**
|
||||
* Extracts the user provided filter values and puts them in the list of parameters.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './logical.js';
|
||||
export * from './filter.js';
|
||||
@@ -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<FilterResult>,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { AbstractSqlClauses, AbstractSqlQuery } from '../../../types/index.js';
|
||||
|
||||
export type FilterResult = {
|
||||
clauses: Required<Pick<AbstractSqlClauses, 'where' | 'joins'>>;
|
||||
parameters: AbstractSqlQuery['parameters'];
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './filter/index.js';
|
||||
export * from './sort.js';
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Pick<AbstractSqlClauses, 'order' | 'joins'>>;
|
||||
|
||||
@@ -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`),
|
||||
}));
|
||||
|
||||
@@ -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;
|
||||
60
packages/data-sql/src/types/abstract-sql.ts
Normal file
60
packages/data-sql/src/types/abstract-sql.ts
Normal file
@@ -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<string, string[]>;
|
||||
|
||||
/* 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<string | number>) => AbstractSqlQuery;
|
||||
localJoinFields: AtLeastOneElement<string>;
|
||||
foreignJoinFields: AtLeastOneElement<string>;
|
||||
alias: string;
|
||||
}
|
||||
16
packages/data-sql/src/types/clauses.ts
Normal file
16
packages/data-sql/src/types/clauses.ts
Normal file
@@ -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[];
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -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.
|
||||
@@ -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';
|
||||
|
||||
4
packages/data-sql/src/types/clauses/select/column.ts
Normal file
4
packages/data-sql/src/types/clauses/select/column.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface AbstractSqlQueryColumn {
|
||||
table: string;
|
||||
column: string;
|
||||
}
|
||||
@@ -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.
|
||||
4
packages/data-sql/src/types/clauses/select/index.ts
Normal file
4
packages/data-sql/src/types/clauses/select/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './column.js';
|
||||
export * from './fn.js';
|
||||
export * from './json.js';
|
||||
export * from './primitive.js';
|
||||
@@ -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.
|
||||
4
packages/data-sql/src/types/clauses/where.ts
Normal file
4
packages/data-sql/src/types/clauses/where.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { AbstractSqlQueryConditionNode } from './where/condition.js';
|
||||
import type { AbstractSqlQueryLogicalNode } from './where/logical.js';
|
||||
|
||||
export type AbstractSqlQueryWhereNode = AbstractSqlQueryConditionNode | AbstractSqlQueryLogicalNode;
|
||||
21
packages/data-sql/src/types/clauses/where/condition.ts
Normal file
21
packages/data-sql/src/types/clauses/where/condition.ts
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './condition.js';
|
||||
export * from './conditions/index.js';
|
||||
export * from './logical.js';
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<string, string[]>;
|
||||
|
||||
/* 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<string | number>) => AbstractSqlQuery;
|
||||
localJoinFields: AtLeastOneElement<string>;
|
||||
foreignJoinFields: AtLeastOneElement<string>;
|
||||
alias: string;
|
||||
}
|
||||
|
||||
export * from './abstract-sql.js';
|
||||
export * from './clauses.js';
|
||||
export * from './clauses/index.js';
|
||||
export * from './parameterized-statement.js';
|
||||
|
||||
Reference in New Issue
Block a user