flowquery 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +30 -0
- package/.github/workflows/release.yml +84 -0
- package/CODE_OF_CONDUCT.md +10 -0
- package/FlowQueryLogoIcon.png +0 -0
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/SECURITY.md +14 -0
- package/SUPPORT.md +13 -0
- package/docs/flowquery.min.js +1 -0
- package/docs/index.html +105 -0
- package/flowquery-vscode/.vscode-test.mjs +5 -0
- package/flowquery-vscode/.vscodeignore +13 -0
- package/flowquery-vscode/LICENSE +21 -0
- package/flowquery-vscode/README.md +11 -0
- package/flowquery-vscode/demo/FlowQueryVSCodeDemo.gif +0 -0
- package/flowquery-vscode/eslint.config.mjs +25 -0
- package/flowquery-vscode/extension.js +508 -0
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -0
- package/flowquery-vscode/flowquery-worker.js +66 -0
- package/flowquery-vscode/images/FlowQueryLogoIcon.png +0 -0
- package/flowquery-vscode/jsconfig.json +13 -0
- package/flowquery-vscode/libs/page.css +53 -0
- package/flowquery-vscode/libs/table.css +13 -0
- package/flowquery-vscode/libs/tabs.css +66 -0
- package/flowquery-vscode/package-lock.json +2917 -0
- package/flowquery-vscode/package.json +51 -0
- package/flowquery-vscode/test/extension.test.js +196 -0
- package/flowquery-vscode/test/worker.test.js +25 -0
- package/flowquery-vscode/vsc-extension-quickstart.md +42 -0
- package/jest.config.js +11 -0
- package/package.json +28 -0
- package/queries/analyze_catfacts.cql +75 -0
- package/queries/azure_openai_completions.cql +13 -0
- package/queries/azure_openai_models.cql +9 -0
- package/queries/mock_pipeline.cql +84 -0
- package/queries/openai_completions.cql +15 -0
- package/queries/openai_models.cql +13 -0
- package/queries/test.cql +6 -0
- package/queries/tool_inference.cql +24 -0
- package/queries/wisdom.cql +6 -0
- package/queries/wisdom_letter_histogram.cql +8 -0
- package/src/compute/runner.ts +65 -0
- package/src/index.browser.ts +11 -0
- package/src/index.ts +12 -0
- package/src/io/command_line.ts +74 -0
- package/src/parsing/alias.ts +23 -0
- package/src/parsing/alias_option.ts +5 -0
- package/src/parsing/ast_node.ts +153 -0
- package/src/parsing/base_parser.ts +92 -0
- package/src/parsing/components/csv.ts +9 -0
- package/src/parsing/components/from.ts +12 -0
- package/src/parsing/components/headers.ts +12 -0
- package/src/parsing/components/json.ts +9 -0
- package/src/parsing/components/null.ts +9 -0
- package/src/parsing/components/post.ts +9 -0
- package/src/parsing/components/text.ts +9 -0
- package/src/parsing/context.ts +48 -0
- package/src/parsing/data_structures/associative_array.ts +43 -0
- package/src/parsing/data_structures/json_array.ts +31 -0
- package/src/parsing/data_structures/key_value_pair.ts +37 -0
- package/src/parsing/data_structures/lookup.ts +40 -0
- package/src/parsing/data_structures/range_lookup.ts +36 -0
- package/src/parsing/expressions/expression.ts +142 -0
- package/src/parsing/expressions/f_string.ts +26 -0
- package/src/parsing/expressions/identifier.ts +22 -0
- package/src/parsing/expressions/number.ts +40 -0
- package/src/parsing/expressions/operator.ts +179 -0
- package/src/parsing/expressions/reference.ts +42 -0
- package/src/parsing/expressions/string.ts +34 -0
- package/src/parsing/functions/aggregate_function.ts +58 -0
- package/src/parsing/functions/avg.ts +37 -0
- package/src/parsing/functions/collect.ts +44 -0
- package/src/parsing/functions/function.ts +60 -0
- package/src/parsing/functions/function_factory.ts +66 -0
- package/src/parsing/functions/join.ts +26 -0
- package/src/parsing/functions/predicate_function.ts +44 -0
- package/src/parsing/functions/predicate_function_factory.ts +15 -0
- package/src/parsing/functions/predicate_sum.ts +29 -0
- package/src/parsing/functions/rand.ts +13 -0
- package/src/parsing/functions/range.ts +18 -0
- package/src/parsing/functions/reducer_element.ts +10 -0
- package/src/parsing/functions/replace.ts +19 -0
- package/src/parsing/functions/round.ts +17 -0
- package/src/parsing/functions/size.ts +17 -0
- package/src/parsing/functions/split.ts +26 -0
- package/src/parsing/functions/stringify.ts +26 -0
- package/src/parsing/functions/sum.ts +31 -0
- package/src/parsing/functions/to_json.ts +17 -0
- package/src/parsing/functions/value_holder.ts +13 -0
- package/src/parsing/logic/case.ts +26 -0
- package/src/parsing/logic/else.ts +12 -0
- package/src/parsing/logic/end.ts +9 -0
- package/src/parsing/logic/then.ts +12 -0
- package/src/parsing/logic/when.ts +12 -0
- package/src/parsing/operations/aggregated_return.ts +18 -0
- package/src/parsing/operations/aggregated_with.ts +18 -0
- package/src/parsing/operations/group_by.ts +124 -0
- package/src/parsing/operations/limit.ts +22 -0
- package/src/parsing/operations/load.ts +92 -0
- package/src/parsing/operations/operation.ts +65 -0
- package/src/parsing/operations/projection.ts +18 -0
- package/src/parsing/operations/return.ts +43 -0
- package/src/parsing/operations/unwind.ts +32 -0
- package/src/parsing/operations/where.ts +38 -0
- package/src/parsing/operations/with.ts +20 -0
- package/src/parsing/parser.ts +762 -0
- package/src/parsing/token_to_node.ts +91 -0
- package/src/tokenization/keyword.ts +43 -0
- package/src/tokenization/operator.ts +25 -0
- package/src/tokenization/string_walker.ts +194 -0
- package/src/tokenization/symbol.ts +15 -0
- package/src/tokenization/token.ts +633 -0
- package/src/tokenization/token_mapper.ts +53 -0
- package/src/tokenization/token_type.ts +15 -0
- package/src/tokenization/tokenizer.ts +229 -0
- package/src/tokenization/trie.ts +117 -0
- package/src/utils/object_utils.ts +17 -0
- package/src/utils/string_utils.ts +114 -0
- package/tests/compute/runner.test.ts +498 -0
- package/tests/parsing/context.test.ts +27 -0
- package/tests/parsing/expression.test.ts +40 -0
- package/tests/parsing/parser.test.ts +434 -0
- package/tests/tokenization/token_mapper.test.ts +47 -0
- package/tests/tokenization/tokenizer.test.ts +67 -0
- package/tests/tokenization/trie.test.ts +20 -0
- package/tsconfig.json +15 -0
- package/typedoc.json +16 -0
- package/webpack.config.js +26 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import Expression from "../expressions/expression";
|
|
2
|
+
import AggregateFunction from "../functions/aggregate_function";
|
|
3
|
+
import AggregationElement from "../functions/reducer_element";
|
|
4
|
+
import Projection from "./projection";
|
|
5
|
+
import Where from "./where";
|
|
6
|
+
|
|
7
|
+
class Node {
|
|
8
|
+
private _value: any;
|
|
9
|
+
private _children: Map<string, Node> = new Map();
|
|
10
|
+
private _elements: AggregationElement[] | null = null;
|
|
11
|
+
constructor(value: any = null) {
|
|
12
|
+
this._value = value;
|
|
13
|
+
}
|
|
14
|
+
public get value(): any {
|
|
15
|
+
return this._value;
|
|
16
|
+
}
|
|
17
|
+
public get children(): Map<string, Node> {
|
|
18
|
+
return this._children;
|
|
19
|
+
}
|
|
20
|
+
public get elements(): AggregationElement[] | null {
|
|
21
|
+
return this._elements;
|
|
22
|
+
}
|
|
23
|
+
public set elements(elements: AggregationElement[]) {
|
|
24
|
+
this._elements = elements;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class GroupBy extends Projection {
|
|
29
|
+
private _root: Node = new Node();
|
|
30
|
+
private _current: Node = this._root;
|
|
31
|
+
private _mappers: Expression[] | null = null;
|
|
32
|
+
private _reducers: AggregateFunction[] | null = null;
|
|
33
|
+
protected _where: Where | null = null;
|
|
34
|
+
public async run(): Promise<void> {
|
|
35
|
+
this.resetTree();
|
|
36
|
+
this.map();
|
|
37
|
+
this.reduce();
|
|
38
|
+
}
|
|
39
|
+
private get root(): Node {
|
|
40
|
+
return this._root;
|
|
41
|
+
}
|
|
42
|
+
private get current(): Node {
|
|
43
|
+
return this._current;
|
|
44
|
+
}
|
|
45
|
+
private set current(node: Node) {
|
|
46
|
+
this._current = node;
|
|
47
|
+
}
|
|
48
|
+
private resetTree() {
|
|
49
|
+
this.current = this.root;
|
|
50
|
+
}
|
|
51
|
+
private map() {
|
|
52
|
+
let node: Node = this.current;
|
|
53
|
+
for(const mapper of this.mappers) {
|
|
54
|
+
const value: any = mapper.value();
|
|
55
|
+
let child: Node | undefined = node.children.get(value);
|
|
56
|
+
if(child === undefined) {
|
|
57
|
+
child = new Node(value);
|
|
58
|
+
node.children.set(value, child);
|
|
59
|
+
}
|
|
60
|
+
node = child;
|
|
61
|
+
}
|
|
62
|
+
this.current = node;
|
|
63
|
+
}
|
|
64
|
+
private reduce() {
|
|
65
|
+
if(this.current.elements === null) {
|
|
66
|
+
this.current.elements = this.reducers.map(reducer => reducer.element());
|
|
67
|
+
}
|
|
68
|
+
const elements: AggregationElement[] = this.current.elements;
|
|
69
|
+
this.reducers.forEach((reducer, index) => {
|
|
70
|
+
reducer.reduce(elements[index]);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
private get mappers(): Expression[] {
|
|
74
|
+
if(this._mappers === null) {
|
|
75
|
+
this._mappers = [...this._generate_mappers()];
|
|
76
|
+
}
|
|
77
|
+
return this._mappers;
|
|
78
|
+
}
|
|
79
|
+
private *_generate_mappers(): Generator<Expression> {
|
|
80
|
+
for(const [expression, _] of this.expressions()) {
|
|
81
|
+
if(expression.mappable()) {
|
|
82
|
+
yield expression;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
private get reducers(): AggregateFunction[] {
|
|
87
|
+
if(this._reducers === null) {
|
|
88
|
+
this._reducers = this.children.map((child) => {
|
|
89
|
+
return (child as Expression).reducers();
|
|
90
|
+
}).flat();
|
|
91
|
+
}
|
|
92
|
+
return this._reducers;
|
|
93
|
+
}
|
|
94
|
+
public *generate_results(mapperIndex: number = 0, node: Node = this.root): Generator<Record<string, any>> {
|
|
95
|
+
if(node.children.size > 0) {
|
|
96
|
+
for(const child of node.children.values()) {
|
|
97
|
+
this.mappers[mapperIndex].overridden = child.value;
|
|
98
|
+
yield* this.generate_results(mapperIndex + 1, child);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
node.elements?.forEach((element, reducerIndex) => {
|
|
102
|
+
this.reducers[reducerIndex].overridden = element.value;
|
|
103
|
+
});
|
|
104
|
+
const record: Record<string, any> = {};
|
|
105
|
+
for(const [expression, alias] of this.expressions()) {
|
|
106
|
+
record[alias] = expression.value();
|
|
107
|
+
}
|
|
108
|
+
if(this.where) {
|
|
109
|
+
yield record;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
public set where(where: Where) {
|
|
114
|
+
this._where = where;
|
|
115
|
+
}
|
|
116
|
+
public get where(): boolean {
|
|
117
|
+
if(this._where === null) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return this._where.value();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export default GroupBy;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Operation from "./operation";
|
|
2
|
+
|
|
3
|
+
class Limit extends Operation {
|
|
4
|
+
private count: number = 0;
|
|
5
|
+
private limit: number = 0;
|
|
6
|
+
constructor(limit: number) {
|
|
7
|
+
super();
|
|
8
|
+
this.limit = limit;
|
|
9
|
+
}
|
|
10
|
+
public async run(): Promise<void> {
|
|
11
|
+
if (this.count >= this.limit) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
this.count++;
|
|
15
|
+
await this.next?.run();
|
|
16
|
+
}
|
|
17
|
+
public reset(): void {
|
|
18
|
+
this.count = 0;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default Limit;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Operation from "./operation";
|
|
2
|
+
import CSV from "../components/csv";
|
|
3
|
+
import {default as _JSON} from "../components/json";
|
|
4
|
+
import Text from "../components/text";
|
|
5
|
+
import Function from "../functions/function";
|
|
6
|
+
import AssociativeArray from "../data_structures/associative_array";
|
|
7
|
+
import Reference from "../expressions/reference";
|
|
8
|
+
import Expression from "../expressions/expression";
|
|
9
|
+
import Headers from "../components/headers";
|
|
10
|
+
import Post from "../components/post";
|
|
11
|
+
import Lookup from "../data_structures/lookup";
|
|
12
|
+
|
|
13
|
+
class Load extends Operation {
|
|
14
|
+
private _value: any = null;
|
|
15
|
+
constructor() {
|
|
16
|
+
super()
|
|
17
|
+
}
|
|
18
|
+
public get type(): _JSON | CSV | Text {
|
|
19
|
+
return this.children[0] as _JSON | CSV | Text;
|
|
20
|
+
}
|
|
21
|
+
public get from(): string {
|
|
22
|
+
return this.children[1].value() as string;
|
|
23
|
+
}
|
|
24
|
+
public get headers(): { [key: string]: string } {
|
|
25
|
+
if(this.childCount() > 2 && this.children[2] instanceof Headers) {
|
|
26
|
+
return this.children[2].value() as { [key: string]: string } || {};
|
|
27
|
+
}
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
public get payload(): Function | Reference | Expression | AssociativeArray | Lookup | null {
|
|
31
|
+
let post: Post | null = null;
|
|
32
|
+
if(this.childCount() > 2 && this.children[2] instanceof Post) {
|
|
33
|
+
post = this.children[2] as Post;
|
|
34
|
+
} else if(this.childCount() > 3 && this.children[3] instanceof Post) {
|
|
35
|
+
post = this.children[3] as Post;
|
|
36
|
+
}
|
|
37
|
+
return post !== null ? post.firstChild() as Function | Reference | Expression | AssociativeArray | Lookup : null;
|
|
38
|
+
}
|
|
39
|
+
private method(): "GET" | "POST" {
|
|
40
|
+
if(this.payload === null) {
|
|
41
|
+
return "GET";
|
|
42
|
+
} else {
|
|
43
|
+
return "POST";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
private options(): object {
|
|
47
|
+
const headers = this.headers as { [key: string]: string };
|
|
48
|
+
const payload = this.payload;
|
|
49
|
+
const data = payload?.value();
|
|
50
|
+
if(data !== null && typeof data === "object" && !(headers.hasOwnProperty("Content-Type"))) {
|
|
51
|
+
headers["Content-Type"] = "application/json";
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
"method": this.method(),
|
|
55
|
+
"headers": headers,
|
|
56
|
+
...(payload !== null ? {"body": JSON.stringify(payload.value())} : {})
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
public async load(): Promise<any> {
|
|
60
|
+
const result = await fetch(this.from, this.options());
|
|
61
|
+
let data: any = null;
|
|
62
|
+
if(this.type instanceof _JSON) {
|
|
63
|
+
data = await result.json();
|
|
64
|
+
} else if(this.type instanceof Text) {
|
|
65
|
+
data = await result.text();
|
|
66
|
+
}
|
|
67
|
+
if(Array.isArray(data)) {
|
|
68
|
+
for(const item of data) {
|
|
69
|
+
this._value = item;
|
|
70
|
+
await this.next?.run();
|
|
71
|
+
}
|
|
72
|
+
} else if(typeof data === "object" && data !== null) {
|
|
73
|
+
this._value = data;
|
|
74
|
+
await this.next?.run();
|
|
75
|
+
} else if(typeof data === "string") {
|
|
76
|
+
this._value = data;
|
|
77
|
+
await this.next?.run();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
public async run(): Promise<void> {
|
|
81
|
+
try {
|
|
82
|
+
await this.load();
|
|
83
|
+
} catch(e) {
|
|
84
|
+
throw new Error(`Failed to load data from ${this.from}. Error: ${e}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
public value(): any {
|
|
88
|
+
return this._value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export default Load;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import ASTNode from "../ast_node";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base class for all FlowQuery operations.
|
|
5
|
+
*
|
|
6
|
+
* Operations represent the main statements in FlowQuery (WITH, UNWIND, RETURN, LOAD, WHERE).
|
|
7
|
+
* They form a linked list structure and can be executed sequentially.
|
|
8
|
+
*
|
|
9
|
+
* @abstract
|
|
10
|
+
*/
|
|
11
|
+
abstract class Operation extends ASTNode {
|
|
12
|
+
private _previous: Operation | null = null;
|
|
13
|
+
private _next: Operation | null = null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new Operation instance.
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
}
|
|
21
|
+
public get previous(): Operation | null {
|
|
22
|
+
return this._previous;
|
|
23
|
+
}
|
|
24
|
+
public set previous(value: Operation | null) {
|
|
25
|
+
this._previous = value;
|
|
26
|
+
}
|
|
27
|
+
public get next(): Operation | null {
|
|
28
|
+
return this._next;
|
|
29
|
+
}
|
|
30
|
+
public set next(value: Operation | null) {
|
|
31
|
+
this._next = value;
|
|
32
|
+
}
|
|
33
|
+
public addSibling(operation: Operation): void {
|
|
34
|
+
this._parent?.addChild(operation);
|
|
35
|
+
operation.previous = this;
|
|
36
|
+
this.next = operation;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Executes this operation. Must be implemented by subclasses.
|
|
41
|
+
*
|
|
42
|
+
* @returns A promise that resolves when the operation completes
|
|
43
|
+
* @throws {Error} If not implemented by subclass
|
|
44
|
+
*/
|
|
45
|
+
public async run(): Promise<void> {
|
|
46
|
+
throw new Error('Not implemented');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Finishes execution by calling finish on the next operation in the chain.
|
|
51
|
+
*
|
|
52
|
+
* @returns A promise that resolves when all operations finish
|
|
53
|
+
*/
|
|
54
|
+
public async finish(): Promise<void> {
|
|
55
|
+
await this.next?.finish();
|
|
56
|
+
}
|
|
57
|
+
public reset(): void {
|
|
58
|
+
;
|
|
59
|
+
}
|
|
60
|
+
public get results(): Record<string, any>[] {
|
|
61
|
+
throw new Error('Not implemented');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default Operation;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Operation from "./operation";
|
|
2
|
+
import Expression from "../expressions/expression";
|
|
3
|
+
|
|
4
|
+
class Projection extends Operation {
|
|
5
|
+
constructor(expressions: Expression[]) {
|
|
6
|
+
super();
|
|
7
|
+
this.children = expressions;
|
|
8
|
+
}
|
|
9
|
+
protected *expressions(): Generator<[Expression, string]> {
|
|
10
|
+
for(let i = 0; i < this.children.length; i++) {
|
|
11
|
+
const expression: Expression = this.children[i] as Expression;
|
|
12
|
+
const alias = expression.alias || `expr${i}`;
|
|
13
|
+
yield [expression, alias];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default Projection;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Projection from "./projection";
|
|
2
|
+
import Where from "./where";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents a RETURN operation that produces the final query results.
|
|
6
|
+
*
|
|
7
|
+
* The RETURN operation evaluates expressions and collects them into result records.
|
|
8
|
+
* It can optionally have a WHERE clause to filter results.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // RETURN x, y WHERE x > 0
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
class Return extends Projection {
|
|
16
|
+
protected _where: Where | null = null;
|
|
17
|
+
protected _results: Record<string, any>[] = [];
|
|
18
|
+
public set where(where: Where) {
|
|
19
|
+
this._where = where;
|
|
20
|
+
}
|
|
21
|
+
public get where(): boolean {
|
|
22
|
+
if(this._where === null) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return this._where.value();
|
|
26
|
+
}
|
|
27
|
+
public async run(): Promise<void> {
|
|
28
|
+
if(!this.where) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const record: Map<string, any> = new Map();
|
|
32
|
+
for(const [expression, alias] of this.expressions()) {
|
|
33
|
+
const value: any = expression.value();
|
|
34
|
+
record.set(alias, value);
|
|
35
|
+
}
|
|
36
|
+
this._results.push(Object.fromEntries(record));
|
|
37
|
+
}
|
|
38
|
+
public get results(): Record<string, any>[] {
|
|
39
|
+
return this._results;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default Return;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Operation from "./operation";
|
|
2
|
+
import Expression from "../expressions/expression";
|
|
3
|
+
|
|
4
|
+
class Unwind extends Operation {
|
|
5
|
+
private _value: any;
|
|
6
|
+
constructor(expression: Expression) {
|
|
7
|
+
super();
|
|
8
|
+
this.addChild(expression);
|
|
9
|
+
}
|
|
10
|
+
public get expression(): Expression {
|
|
11
|
+
return this.children[0] as Expression;
|
|
12
|
+
}
|
|
13
|
+
public get as(): string {
|
|
14
|
+
return this.children[1].value as unknown as string;
|
|
15
|
+
}
|
|
16
|
+
public async run(): Promise<void> {
|
|
17
|
+
const expression = this.expression.value();
|
|
18
|
+
if(!(Array.isArray(expression))) {
|
|
19
|
+
throw new Error('Expected array');
|
|
20
|
+
}
|
|
21
|
+
for(let i = 0; i < expression.length; i++) {
|
|
22
|
+
this._value = expression[i];
|
|
23
|
+
await this.next?.run();
|
|
24
|
+
}
|
|
25
|
+
this.next?.reset();
|
|
26
|
+
}
|
|
27
|
+
public value(): any {
|
|
28
|
+
return this._value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default Unwind;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Operation from "./operation";
|
|
2
|
+
import Expression from "../expressions/expression";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents a WHERE operation that filters data based on a condition.
|
|
6
|
+
*
|
|
7
|
+
* The WHERE operation evaluates a boolean expression and only continues
|
|
8
|
+
* execution to the next operation if the condition is true.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // RETURN x WHERE x > 0
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
class Where extends Operation {
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new WHERE operation with the given condition.
|
|
18
|
+
*
|
|
19
|
+
* @param expression - The boolean expression to evaluate
|
|
20
|
+
*/
|
|
21
|
+
constructor(expression: Expression) {
|
|
22
|
+
super();
|
|
23
|
+
this.addChild(expression);
|
|
24
|
+
}
|
|
25
|
+
public get expression(): Expression {
|
|
26
|
+
return this.children[0] as Expression;
|
|
27
|
+
}
|
|
28
|
+
public async run(): Promise<void> {
|
|
29
|
+
if(this.expression.value()) {
|
|
30
|
+
await this.next?.run();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
public value(): any {
|
|
34
|
+
return this.expression.value();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default Where;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Projection from "./projection";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a WITH operation that defines variables or intermediate results.
|
|
5
|
+
*
|
|
6
|
+
* The WITH operation creates named expressions that can be referenced later in the query.
|
|
7
|
+
* It passes control to the next operation in the chain.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // WITH x = 1, y = 2 RETURN x + y
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
class With extends Projection {
|
|
15
|
+
public async run(): Promise<void> {
|
|
16
|
+
await this.next?.run();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default With;
|