diff --git a/src/nodes/expressionComparatorExpression.ts b/src/nodes/expressionComparatorExpression.ts new file mode 100644 index 0000000..5d64a72 --- /dev/null +++ b/src/nodes/expressionComparatorExpression.ts @@ -0,0 +1,8 @@ +import { ExpressionConditionComparators } from "./operands"; + +export type ExpressionComparatorExpressions = { + readonly kind: "ExpressionComparatorExpressions"; + readonly key: string; + readonly operation: ExpressionConditionComparators; + readonly value: unknown; +}; diff --git a/src/nodes/filterExpressionJoinTypeNode.ts b/src/nodes/expressionJoinTypeNode.ts similarity index 60% rename from src/nodes/filterExpressionJoinTypeNode.ts rename to src/nodes/expressionJoinTypeNode.ts index 97bfc0c..e589490 100644 --- a/src/nodes/filterExpressionJoinTypeNode.ts +++ b/src/nodes/expressionJoinTypeNode.ts @@ -3,18 +3,18 @@ import { AttributeNotExistsFunctionExpression } from "./attributeNotExistsFuncti import { BeginsWithFunctionExpression } from "./beginsWithFunctionExpression"; import { BetweenConditionExpression } from "./betweenConditionExpression"; import { ContainsFunctionExpression } from "./containsFunctionExpression"; -import { FilterExpressionComparatorExpressions } from "./filterExpressionComparatorExpression"; -import { FilterExpressionNode } from "./filterExpressionNode"; -import { FilterExpressionNotExpression } from "./filterExpressionNotExpression"; +import { ExpressionComparatorExpressions } from "./expressionComparatorExpression"; +import { ExpressionNode } from "./expressionNode"; +import { ExpressionNotExpression } from "./expressionNotExpression"; export type JoinType = "AND" | "OR"; -export type FilterExpressionJoinTypeNode = { - readonly kind: "FilterExpressionJoinTypeNode"; +export type ExpressionJoinTypeNode = { + readonly kind: "ExpressionJoinTypeNode"; readonly expr: - | FilterExpressionNode - | FilterExpressionComparatorExpressions - | FilterExpressionNotExpression + | ExpressionNode + | ExpressionComparatorExpressions + | ExpressionNotExpression | AttributeExistsFunctionExpression | AttributeNotExistsFunctionExpression | BetweenConditionExpression diff --git a/src/nodes/expressionNode.ts b/src/nodes/expressionNode.ts new file mode 100644 index 0000000..390e6c7 --- /dev/null +++ b/src/nodes/expressionNode.ts @@ -0,0 +1,6 @@ +import { ExpressionJoinTypeNode } from "./expressionJoinTypeNode"; + +export type ExpressionNode = { + readonly kind: "ExpressionNode"; + readonly expressions: ExpressionJoinTypeNode[]; +}; diff --git a/src/nodes/expressionNotExpression.ts b/src/nodes/expressionNotExpression.ts new file mode 100644 index 0000000..8325947 --- /dev/null +++ b/src/nodes/expressionNotExpression.ts @@ -0,0 +1,6 @@ +import { ExpressionNode } from "./expressionNode"; + +export type ExpressionNotExpression = { + readonly kind: "ExpressionNotExpression"; + readonly expr: ExpressionNode; +}; diff --git a/src/nodes/filterExpressionComparatorExpression.ts b/src/nodes/filterExpressionComparatorExpression.ts deleted file mode 100644 index 76f0099..0000000 --- a/src/nodes/filterExpressionComparatorExpression.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { FilterConditionComparators } from "./operands"; - -export type FilterExpressionComparatorExpressions = { - readonly kind: "FilterExpressionComparatorExpressions"; - readonly key: string; - readonly operation: FilterConditionComparators; - readonly value: unknown; -}; diff --git a/src/nodes/filterExpressionNode.ts b/src/nodes/filterExpressionNode.ts deleted file mode 100644 index 8213903..0000000 --- a/src/nodes/filterExpressionNode.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { FilterExpressionJoinTypeNode } from "./filterExpressionJoinTypeNode"; - -export type FilterExpressionNode = { - readonly kind: "FilterExpressionNode"; - readonly expressions: FilterExpressionJoinTypeNode[]; -}; diff --git a/src/nodes/filterExpressionNotExpression.ts b/src/nodes/filterExpressionNotExpression.ts deleted file mode 100644 index fd84716..0000000 --- a/src/nodes/filterExpressionNotExpression.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { FilterExpressionNode } from "./filterExpressionNode"; - -export type FilterExpressionNotExpression = { - readonly kind: "FilterExpressionNotExpression"; - readonly expr: FilterExpressionNode; -}; diff --git a/src/nodes/operands.ts b/src/nodes/operands.ts index e8aec33..922a287 100644 --- a/src/nodes/operands.ts +++ b/src/nodes/operands.ts @@ -10,4 +10,4 @@ export type FunctionExpression = export type NotExpression = "NOT"; export type KeyConditionComparators = "=" | "<" | "<=" | ">" | ">="; -export type FilterConditionComparators = KeyConditionComparators | "<>"; +export type ExpressionConditionComparators = KeyConditionComparators | "<>"; diff --git a/src/nodes/queryNode.ts b/src/nodes/queryNode.ts index ece9837..959e7f5 100644 --- a/src/nodes/queryNode.ts +++ b/src/nodes/queryNode.ts @@ -1,6 +1,6 @@ import { AttributesNode } from "./attributesNode"; import { ConsistentReadNode } from "./consistentReadNode"; -import { FilterExpressionNode } from "./filterExpressionNode"; +import { ExpressionNode } from "./expressionNode"; import { KeyConditionNode } from "./keyConditionNode"; import { LimitNode } from "./limitNode"; import { ScanIndexForwardNode } from "./scanIndexForwardNode"; @@ -10,7 +10,7 @@ export type QueryNode = { readonly kind: "QueryNode"; readonly table: TableNode; readonly keyConditions: KeyConditionNode[]; - readonly filterExpression: FilterExpressionNode; + readonly filterExpression: ExpressionNode; readonly consistentRead?: ConsistentReadNode; readonly scanIndexForward?: ScanIndexForwardNode; readonly limit?: LimitNode; diff --git a/src/queryBuilders/queryQueryBuilder.ts b/src/queryBuilders/queryQueryBuilder.ts index 186cee9..6f6f698 100644 --- a/src/queryBuilders/queryQueryBuilder.ts +++ b/src/queryBuilders/queryQueryBuilder.ts @@ -2,12 +2,12 @@ import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb"; import { AttributeExistsFunctionExpression } from "../nodes/attributeExistsFunctionExpression"; import { AttributeNotExistsFunctionExpression } from "../nodes/attributeNotExistsFunctionExpression"; import { - FilterExpressionJoinTypeNode, + ExpressionJoinTypeNode, JoinType, -} from "../nodes/filterExpressionJoinTypeNode"; +} from "../nodes/expressionJoinTypeNode"; import { BetweenExpression, - FilterConditionComparators, + ExpressionConditionComparators, FunctionExpression, KeyConditionComparators, NotExpression, @@ -63,7 +63,7 @@ export interface QueryQueryBuilderInterface { // Regular operand filterExpression>>( key: Exclude, - operation: Key extends NotExpression ? never : FilterConditionComparators, + operation: Key extends NotExpression ? never : ExpressionConditionComparators, val: StripKeys> ): QueryQueryBuilderInterface; @@ -123,7 +123,7 @@ export interface QueryQueryBuilderInterface { // Regular operand orFilterExpression>>( key: Key, - operation: FilterConditionComparators, + operation: ExpressionConditionComparators, val: StripKeys> ): QueryQueryBuilderInterface; @@ -203,7 +203,7 @@ export interface QueryQueryBuilderInterfaceWithOnlyFilterOperations< */ filterExpression>>( key: Key, - operation: FilterConditionComparators, + operation: ExpressionConditionComparators, val: StripKeys> ): QueryQueryBuilderInterfaceWithOnlyFilterOperations; @@ -255,7 +255,7 @@ export interface QueryQueryBuilderInterfaceWithOnlyFilterOperations< */ orFilterExpression>>( key: Key, - operation: FilterConditionComparators, + operation: ExpressionConditionComparators, val: StripKeys> ): QueryQueryBuilderInterfaceWithOnlyFilterOperations; @@ -313,7 +313,7 @@ type FilterExprArgs< > = | [ key: Key, - operation: FilterConditionComparators, + operation: ExpressionConditionComparators, value: StripKeys> ] | [ @@ -452,7 +452,7 @@ export class QueryQueryBuilder< filterExpression: { ...this.#props.node.filterExpression, expressions: this.#props.node.filterExpression.expressions.concat({ - kind: "FilterExpressionJoinTypeNode", + kind: "ExpressionJoinTypeNode", expr: { kind: "BeginsWithFunctionExpression", key, @@ -473,7 +473,7 @@ export class QueryQueryBuilder< filterExpression: { ...this.#props.node.filterExpression, expressions: this.#props.node.filterExpression.expressions.concat({ - kind: "FilterExpressionJoinTypeNode", + kind: "ExpressionJoinTypeNode", expr: { kind: "ContainsFunctionExpression", key, @@ -506,7 +506,7 @@ export class QueryQueryBuilder< filterExpression: { ...this.#props.node.filterExpression, expressions: this.#props.node.filterExpression.expressions.concat({ - kind: "FilterExpressionJoinTypeNode", + kind: "ExpressionJoinTypeNode", expr: resultExpr, joinType, }), @@ -523,7 +523,7 @@ export class QueryQueryBuilder< filterExpression: { ...this.#props.node.filterExpression, expressions: this.#props.node.filterExpression.expressions.concat({ - kind: "FilterExpressionJoinTypeNode", + kind: "ExpressionJoinTypeNode", expr: { kind: "BetweenConditionExpression", key, @@ -551,10 +551,10 @@ export class QueryQueryBuilder< filterExpression: { ...this.#props.node.filterExpression, expressions: this.#props.node.filterExpression.expressions.concat({ - kind: "FilterExpressionJoinTypeNode", + kind: "ExpressionJoinTypeNode", joinType, expr: { - kind: "FilterExpressionComparatorExpressions", + kind: "ExpressionComparatorExpressions", key, operation, value, @@ -580,7 +580,7 @@ export class QueryQueryBuilder< ...this.#props.node, filterExpression: { expressions: [], - kind: "FilterExpressionNode", + kind: "ExpressionNode", }, }, }); @@ -589,8 +589,8 @@ export class QueryQueryBuilder< const { filterExpression } = result._getNode(); - let resultNode: FilterExpressionJoinTypeNode = { - kind: "FilterExpressionJoinTypeNode", + let resultNode: ExpressionJoinTypeNode = { + kind: "ExpressionJoinTypeNode", expr: filterExpression, joinType, }; @@ -599,7 +599,7 @@ export class QueryQueryBuilder< resultNode = { ...resultNode, expr: { - kind: "FilterExpressionNotExpression", + kind: "ExpressionNotExpression", expr: filterExpression, }, }; @@ -621,7 +621,6 @@ export class QueryQueryBuilder< throw new Error("Invalid arguments given to filterExpression"); } - // TODO: Add support for all operations from here: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Syntax filterExpression>>( ...args: FilterExprArgs ): QueryQueryBuilderInterface { diff --git a/src/queryCompiler/queryCompiler.ts b/src/queryCompiler/queryCompiler.ts index 916a0ec..a1e49b8 100644 --- a/src/queryCompiler/queryCompiler.ts +++ b/src/queryCompiler/queryCompiler.ts @@ -1,6 +1,6 @@ import { GetCommand, PutCommand, QueryCommand } from "@aws-sdk/lib-dynamodb"; -import { FilterExpressionJoinTypeNode } from "../nodes/filterExpressionJoinTypeNode"; -import { FilterExpressionNode } from "../nodes/filterExpressionNode"; +import { ExpressionJoinTypeNode } from "../nodes/expressionJoinTypeNode"; +import { ExpressionNode } from "../nodes/expressionNode"; import { GetNode } from "../nodes/getNode"; import { KeyConditionNode } from "../nodes/keyConditionNode"; import { QueryNode } from "../nodes/queryNode"; @@ -68,7 +68,7 @@ export class QueryCompiler { attributeNames ); - const compiledFilterExpression = this.compileFilterExpression( + const compiledFilterExpression = this.compileExpression( filterExpressionNode, filterExpressionAttributeValues, attributeNames @@ -151,8 +151,8 @@ export class QueryCompiler { }; } - compileFilterExpression = ( - expression: FilterExpressionNode, + compileExpression = ( + expression: ExpressionNode, filterExpressionAttributeValues: Map, attributeNames: Map ) => { @@ -174,7 +174,7 @@ export class QueryCompiler { }; compileFilterExpressionJoinNodes = ( - { expr }: FilterExpressionJoinTypeNode, + { expr }: ExpressionJoinTypeNode, filterExpressionAttributeValues: Map, attributeNames: Map ) => { @@ -193,9 +193,9 @@ export class QueryCompiler { } switch (expr.kind) { - case "FilterExpressionNode": { + case "ExpressionNode": { res += "("; - res += this.compileFilterExpression( + res += this.compileExpression( expr, filterExpressionAttributeValues, attributeNames @@ -204,15 +204,15 @@ export class QueryCompiler { break; } - case "FilterExpressionComparatorExpressions": { + case "ExpressionComparatorExpressions": { res += `${attributeName} ${expr.operation} ${attributeValue}`; filterExpressionAttributeValues.set(attributeValue, expr.value); break; } - case "FilterExpressionNotExpression": { + case "ExpressionNotExpression": { res += "NOT ("; - res += this.compileFilterExpression( + res += this.compileExpression( expr.expr, filterExpressionAttributeValues, attributeNames diff --git a/src/queryCreator.ts b/src/queryCreator.ts index 5f5f30d..18d3eca 100644 --- a/src/queryCreator.ts +++ b/src/queryCreator.ts @@ -58,7 +58,7 @@ export class QueryCreator { }, keyConditions: [], filterExpression: { - kind: "FilterExpressionNode", + kind: "ExpressionNode", expressions: [], }, },