flowquery 1.0.15 → 1.0.17
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/python-publish.yml +97 -0
- package/dist/compute/runner.d.ts +3 -2
- package/dist/compute/runner.d.ts.map +1 -1
- package/dist/compute/runner.js +7 -7
- package/dist/compute/runner.js.map +1 -1
- package/dist/flowquery.min.js +1 -1
- package/dist/graph/data.d.ts +31 -0
- package/dist/graph/data.d.ts.map +1 -0
- package/dist/graph/data.js +110 -0
- package/dist/graph/data.js.map +1 -0
- package/dist/graph/database.d.ts +20 -0
- package/dist/graph/database.d.ts.map +1 -0
- package/dist/graph/database.js +77 -0
- package/dist/graph/database.js.map +1 -0
- package/dist/graph/hops.d.ts +11 -0
- package/dist/graph/hops.d.ts.map +1 -0
- package/dist/graph/hops.js +25 -0
- package/dist/graph/hops.js.map +1 -0
- package/dist/graph/node.d.ts +35 -0
- package/dist/graph/node.d.ts.map +1 -0
- package/dist/graph/node.js +113 -0
- package/dist/graph/node.js.map +1 -0
- package/dist/graph/node_data.d.ts +11 -0
- package/dist/graph/node_data.d.ts.map +1 -0
- package/dist/graph/node_data.js +20 -0
- package/dist/graph/node_data.js.map +1 -0
- package/dist/graph/node_reference.d.ts +10 -0
- package/dist/graph/node_reference.d.ts.map +1 -0
- package/dist/graph/node_reference.js +52 -0
- package/dist/graph/node_reference.js.map +1 -0
- package/dist/graph/pattern.d.ts +18 -0
- package/dist/graph/pattern.d.ts.map +1 -0
- package/dist/graph/pattern.js +114 -0
- package/dist/graph/pattern.js.map +1 -0
- package/dist/graph/pattern_expression.d.ts +14 -0
- package/dist/graph/pattern_expression.d.ts.map +1 -0
- package/dist/graph/pattern_expression.js +58 -0
- package/dist/graph/pattern_expression.js.map +1 -0
- package/dist/graph/patterns.d.ts +11 -0
- package/dist/graph/patterns.d.ts.map +1 -0
- package/dist/graph/patterns.js +49 -0
- package/dist/graph/patterns.js.map +1 -0
- package/dist/graph/physical_node.d.ts +10 -0
- package/dist/graph/physical_node.d.ts.map +1 -0
- package/dist/graph/physical_node.js +40 -0
- package/dist/graph/physical_node.js.map +1 -0
- package/dist/graph/physical_relationship.d.ts +10 -0
- package/dist/graph/physical_relationship.d.ts.map +1 -0
- package/dist/graph/physical_relationship.js +40 -0
- package/dist/graph/physical_relationship.js.map +1 -0
- package/dist/graph/relationship.d.ts +40 -0
- package/dist/graph/relationship.d.ts.map +1 -0
- package/dist/graph/relationship.js +124 -0
- package/dist/graph/relationship.js.map +1 -0
- package/dist/graph/relationship_data.d.ts +12 -0
- package/dist/graph/relationship_data.d.ts.map +1 -0
- package/dist/graph/relationship_data.js +40 -0
- package/dist/graph/relationship_data.js.map +1 -0
- package/dist/graph/relationship_match_collector.d.ts +19 -0
- package/dist/graph/relationship_match_collector.d.ts.map +1 -0
- package/dist/graph/relationship_match_collector.js +55 -0
- package/dist/graph/relationship_match_collector.js.map +1 -0
- package/dist/graph/relationship_reference.d.ts +8 -0
- package/dist/graph/relationship_reference.d.ts.map +1 -0
- package/dist/graph/relationship_reference.js +37 -0
- package/dist/graph/relationship_reference.js.map +1 -0
- package/dist/parsing/base_parser.d.ts +1 -0
- package/dist/parsing/base_parser.d.ts.map +1 -1
- package/dist/parsing/base_parser.js +4 -1
- package/dist/parsing/base_parser.js.map +1 -1
- package/dist/parsing/context.d.ts +2 -2
- package/dist/parsing/context.js +5 -5
- package/dist/parsing/expressions/boolean.d.ts +8 -0
- package/dist/parsing/expressions/boolean.d.ts.map +1 -0
- package/dist/parsing/expressions/boolean.js +26 -0
- package/dist/parsing/expressions/boolean.js.map +1 -0
- package/dist/parsing/expressions/expression.d.ts +4 -1
- package/dist/parsing/expressions/expression.d.ts.map +1 -1
- package/dist/parsing/expressions/expression.js +15 -8
- package/dist/parsing/expressions/expression.js.map +1 -1
- package/dist/parsing/expressions/expression_map.d.ts +1 -0
- package/dist/parsing/expressions/expression_map.d.ts.map +1 -1
- package/dist/parsing/expressions/expression_map.js +3 -0
- package/dist/parsing/expressions/expression_map.js.map +1 -1
- package/dist/parsing/expressions/operator.d.ts +1 -1
- package/dist/parsing/expressions/operator.d.ts.map +1 -1
- package/dist/parsing/expressions/operator.js.map +1 -1
- package/dist/parsing/functions/function_factory.d.ts +13 -13
- package/dist/parsing/functions/function_factory.d.ts.map +1 -1
- package/dist/parsing/functions/function_factory.js +20 -18
- package/dist/parsing/functions/function_factory.js.map +1 -1
- package/dist/parsing/operations/call.d.ts.map +1 -1
- package/dist/parsing/operations/call.js +3 -1
- package/dist/parsing/operations/call.js.map +1 -1
- package/dist/parsing/operations/create_node.d.ts +14 -0
- package/dist/parsing/operations/create_node.d.ts.map +1 -0
- package/dist/parsing/operations/create_node.js +51 -0
- package/dist/parsing/operations/create_node.js.map +1 -0
- package/dist/parsing/operations/create_relationship.d.ts +14 -0
- package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
- package/dist/parsing/operations/create_relationship.js +51 -0
- package/dist/parsing/operations/create_relationship.js.map +1 -0
- package/dist/parsing/operations/match.d.ts +15 -0
- package/dist/parsing/operations/match.d.ts.map +1 -0
- package/dist/parsing/operations/match.js +45 -0
- package/dist/parsing/operations/match.js.map +1 -0
- package/dist/parsing/operations/operation.d.ts +1 -0
- package/dist/parsing/operations/operation.d.ts.map +1 -1
- package/dist/parsing/operations/operation.js +6 -0
- package/dist/parsing/operations/operation.js.map +1 -1
- package/dist/parsing/operations/return.d.ts +1 -0
- package/dist/parsing/operations/return.d.ts.map +1 -1
- package/dist/parsing/operations/return.js +7 -1
- package/dist/parsing/operations/return.js.map +1 -1
- package/dist/parsing/operations/where.d.ts +1 -1
- package/dist/parsing/operations/where.d.ts.map +1 -1
- package/dist/parsing/operations/where.js +4 -0
- package/dist/parsing/operations/where.js.map +1 -1
- package/dist/parsing/parser.d.ts +10 -0
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +344 -5
- package/dist/parsing/parser.js.map +1 -1
- package/dist/parsing/token_to_node.d.ts.map +1 -1
- package/dist/parsing/token_to_node.js +7 -0
- package/dist/parsing/token_to_node.js.map +1 -1
- package/dist/tokenization/keyword.d.ts +1 -0
- package/dist/tokenization/keyword.d.ts.map +1 -1
- package/dist/tokenization/keyword.js +1 -0
- package/dist/tokenization/keyword.js.map +1 -1
- package/dist/tokenization/token.d.ts +4 -0
- package/dist/tokenization/token.d.ts.map +1 -1
- package/dist/tokenization/token.js +14 -1
- package/dist/tokenization/token.js.map +1 -1
- package/dist/tokenization/token_type.d.ts +1 -0
- package/dist/tokenization/token_type.d.ts.map +1 -1
- package/dist/tokenization/token_type.js +1 -0
- package/dist/tokenization/token_type.js.map +1 -1
- package/dist/tokenization/tokenizer.d.ts +2 -1
- package/dist/tokenization/tokenizer.d.ts.map +1 -1
- package/dist/tokenization/tokenizer.js +25 -12
- package/dist/tokenization/tokenizer.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-py/README.md +166 -0
- package/flowquery-py/pyproject.toml +75 -0
- package/flowquery-py/setup_env.ps1 +92 -0
- package/flowquery-py/setup_env.sh +87 -0
- package/flowquery-py/src/__init__.py +34 -0
- package/flowquery-py/src/__main__.py +10 -0
- package/flowquery-py/src/compute/__init__.py +5 -0
- package/flowquery-py/src/compute/runner.py +60 -0
- package/flowquery-py/src/extensibility.py +52 -0
- package/flowquery-py/src/graph/__init__.py +31 -0
- package/flowquery-py/src/graph/data.py +118 -0
- package/flowquery-py/src/graph/database.py +82 -0
- package/flowquery-py/src/graph/hops.py +43 -0
- package/flowquery-py/src/graph/node.py +112 -0
- package/flowquery-py/src/graph/node_data.py +26 -0
- package/flowquery-py/src/graph/node_reference.py +49 -0
- package/flowquery-py/src/graph/pattern.py +125 -0
- package/flowquery-py/src/graph/pattern_expression.py +62 -0
- package/flowquery-py/src/graph/patterns.py +42 -0
- package/flowquery-py/src/graph/physical_node.py +40 -0
- package/flowquery-py/src/graph/physical_relationship.py +36 -0
- package/flowquery-py/src/graph/relationship.py +135 -0
- package/flowquery-py/src/graph/relationship_data.py +33 -0
- package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
- package/flowquery-py/src/graph/relationship_reference.py +21 -0
- package/flowquery-py/src/io/__init__.py +5 -0
- package/flowquery-py/src/io/command_line.py +67 -0
- package/flowquery-py/src/parsing/__init__.py +17 -0
- package/flowquery-py/src/parsing/alias.py +20 -0
- package/flowquery-py/src/parsing/alias_option.py +11 -0
- package/flowquery-py/src/parsing/ast_node.py +146 -0
- package/flowquery-py/src/parsing/base_parser.py +84 -0
- package/flowquery-py/src/parsing/components/__init__.py +19 -0
- package/flowquery-py/src/parsing/components/csv.py +8 -0
- package/flowquery-py/src/parsing/components/from_.py +10 -0
- package/flowquery-py/src/parsing/components/headers.py +12 -0
- package/flowquery-py/src/parsing/components/json.py +8 -0
- package/flowquery-py/src/parsing/components/null.py +10 -0
- package/flowquery-py/src/parsing/components/post.py +8 -0
- package/flowquery-py/src/parsing/components/text.py +8 -0
- package/flowquery-py/src/parsing/context.py +50 -0
- package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
- package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
- package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
- package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
- package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
- package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
- package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
- package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
- package/flowquery-py/src/parsing/expressions/expression.py +138 -0
- package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
- package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
- package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
- package/flowquery-py/src/parsing/expressions/number.py +32 -0
- package/flowquery-py/src/parsing/expressions/operator.py +169 -0
- package/flowquery-py/src/parsing/expressions/reference.py +47 -0
- package/flowquery-py/src/parsing/expressions/string.py +27 -0
- package/flowquery-py/src/parsing/functions/__init__.py +75 -0
- package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
- package/flowquery-py/src/parsing/functions/async_function.py +62 -0
- package/flowquery-py/src/parsing/functions/avg.py +55 -0
- package/flowquery-py/src/parsing/functions/collect.py +75 -0
- package/flowquery-py/src/parsing/functions/function.py +68 -0
- package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
- package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
- package/flowquery-py/src/parsing/functions/functions.py +59 -0
- package/flowquery-py/src/parsing/functions/join.py +47 -0
- package/flowquery-py/src/parsing/functions/keys.py +34 -0
- package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
- package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
- package/flowquery-py/src/parsing/functions/rand.py +28 -0
- package/flowquery-py/src/parsing/functions/range_.py +34 -0
- package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
- package/flowquery-py/src/parsing/functions/replace.py +37 -0
- package/flowquery-py/src/parsing/functions/round_.py +32 -0
- package/flowquery-py/src/parsing/functions/size.py +32 -0
- package/flowquery-py/src/parsing/functions/split.py +47 -0
- package/flowquery-py/src/parsing/functions/stringify.py +47 -0
- package/flowquery-py/src/parsing/functions/sum.py +51 -0
- package/flowquery-py/src/parsing/functions/to_json.py +33 -0
- package/flowquery-py/src/parsing/functions/type_.py +47 -0
- package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
- package/flowquery-py/src/parsing/logic/__init__.py +15 -0
- package/flowquery-py/src/parsing/logic/case.py +29 -0
- package/flowquery-py/src/parsing/logic/else_.py +12 -0
- package/flowquery-py/src/parsing/logic/end.py +8 -0
- package/flowquery-py/src/parsing/logic/then.py +12 -0
- package/flowquery-py/src/parsing/logic/when.py +10 -0
- package/flowquery-py/src/parsing/operations/__init__.py +35 -0
- package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
- package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
- package/flowquery-py/src/parsing/operations/call.py +74 -0
- package/flowquery-py/src/parsing/operations/create_node.py +34 -0
- package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
- package/flowquery-py/src/parsing/operations/group_by.py +130 -0
- package/flowquery-py/src/parsing/operations/limit.py +22 -0
- package/flowquery-py/src/parsing/operations/load.py +140 -0
- package/flowquery-py/src/parsing/operations/match.py +29 -0
- package/flowquery-py/src/parsing/operations/operation.py +69 -0
- package/flowquery-py/src/parsing/operations/projection.py +21 -0
- package/flowquery-py/src/parsing/operations/return_op.py +50 -0
- package/flowquery-py/src/parsing/operations/unwind.py +37 -0
- package/flowquery-py/src/parsing/operations/where.py +41 -0
- package/flowquery-py/src/parsing/operations/with_op.py +18 -0
- package/flowquery-py/src/parsing/parser.py +1011 -0
- package/flowquery-py/src/parsing/token_to_node.py +109 -0
- package/flowquery-py/src/tokenization/__init__.py +23 -0
- package/flowquery-py/src/tokenization/keyword.py +48 -0
- package/flowquery-py/src/tokenization/operator.py +29 -0
- package/flowquery-py/src/tokenization/string_walker.py +158 -0
- package/flowquery-py/src/tokenization/symbol.py +19 -0
- package/flowquery-py/src/tokenization/token.py +659 -0
- package/flowquery-py/src/tokenization/token_mapper.py +52 -0
- package/flowquery-py/src/tokenization/token_type.py +21 -0
- package/flowquery-py/src/tokenization/tokenizer.py +214 -0
- package/flowquery-py/src/tokenization/trie.py +124 -0
- package/flowquery-py/src/utils/__init__.py +6 -0
- package/flowquery-py/src/utils/object_utils.py +20 -0
- package/flowquery-py/src/utils/string_utils.py +113 -0
- package/flowquery-py/tests/__init__.py +1 -0
- package/flowquery-py/tests/compute/__init__.py +1 -0
- package/flowquery-py/tests/compute/test_runner.py +1335 -0
- package/flowquery-py/tests/graph/__init__.py +1 -0
- package/flowquery-py/tests/graph/test_create.py +56 -0
- package/flowquery-py/tests/graph/test_data.py +73 -0
- package/flowquery-py/tests/graph/test_match.py +40 -0
- package/flowquery-py/tests/parsing/__init__.py +1 -0
- package/flowquery-py/tests/parsing/test_context.py +34 -0
- package/flowquery-py/tests/parsing/test_expression.py +49 -0
- package/flowquery-py/tests/parsing/test_parser.py +674 -0
- package/flowquery-py/tests/test_extensibility.py +611 -0
- package/flowquery-py/tests/tokenization/__init__.py +1 -0
- package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
- package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
- package/flowquery-py/tests/tokenization/test_trie.py +30 -0
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/package.json +1 -1
- package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
- package/misc/apps/RAG/src/components/index.ts +19 -10
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +21 -26
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +24 -25
- package/misc/apps/RAG/src/plugins/loaders/Form.ts +163 -147
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +103 -90
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +80 -130
- package/misc/apps/RAG/src/plugins/loaders/Table.ts +104 -101
- package/misc/apps/RAG/src/plugins/loaders/Weather.ts +47 -36
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +89 -78
- package/package.json +1 -1
- package/src/compute/runner.ts +24 -19
- package/src/graph/data.ts +112 -0
- package/src/graph/database.ts +63 -0
- package/src/graph/hops.ts +22 -0
- package/src/graph/node.ts +99 -0
- package/src/graph/node_data.ts +18 -0
- package/src/graph/node_reference.ts +33 -0
- package/src/graph/pattern.ts +101 -0
- package/src/graph/pattern_expression.ts +37 -0
- package/src/graph/patterns.ts +36 -0
- package/src/graph/physical_node.ts +23 -0
- package/src/graph/physical_relationship.ts +23 -0
- package/src/graph/relationship.ts +116 -0
- package/src/graph/relationship_data.ts +27 -0
- package/src/graph/relationship_match_collector.ts +58 -0
- package/src/graph/relationship_reference.ts +24 -0
- package/src/parsing/base_parser.ts +20 -14
- package/src/parsing/context.ts +14 -14
- package/src/parsing/expressions/boolean.ts +21 -0
- package/src/parsing/expressions/expression.ts +34 -26
- package/src/parsing/expressions/expression_map.ts +3 -0
- package/src/parsing/expressions/operator.ts +19 -1
- package/src/parsing/functions/function_factory.ts +45 -45
- package/src/parsing/operations/call.ts +3 -1
- package/src/parsing/operations/create_node.ts +39 -0
- package/src/parsing/operations/create_relationship.ts +38 -0
- package/src/parsing/operations/match.ts +31 -0
- package/src/parsing/operations/operation.ts +3 -0
- package/src/parsing/operations/return.ts +11 -7
- package/src/parsing/operations/where.ts +10 -6
- package/src/parsing/parser.ts +346 -8
- package/src/parsing/token_to_node.ts +6 -0
- package/src/tokenization/keyword.ts +41 -40
- package/src/tokenization/token.ts +21 -1
- package/src/tokenization/token_type.ts +2 -1
- package/src/tokenization/tokenizer.ts +52 -31
- package/tests/compute/runner.test.ts +660 -6
- package/tests/extensibility.test.ts +97 -93
- package/tests/graph/create.test.ts +36 -0
- package/tests/graph/data.test.ts +58 -0
- package/tests/graph/match.test.ts +29 -0
- package/tests/parsing/parser.test.ts +276 -8
- package/tests/tokenization/tokenizer.test.ts +107 -17
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FlowQuery System Prompt Generator
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Generates a system prompt that instructs the LLM to create FlowQuery statements
|
|
5
5
|
* based on natural language queries, with awareness of available loader plugins.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* Uses FlowQuery's built-in functions() introspection to dynamically discover
|
|
8
8
|
* available async data loaders and their metadata.
|
|
9
9
|
*/
|
|
10
|
+
import { FunctionMetadata, OutputSchema, ParameterSchema } from "flowquery/extensibility";
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
-
import { getAllPluginMetadata, getAvailableLoaders } from '../plugins';
|
|
12
|
+
import { getAllPluginMetadata, getAvailableLoaders } from "../plugins";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* FlowQuery language reference documentation.
|
|
@@ -28,25 +28,29 @@ FlowQuery is a declarative query language for data processing pipelines. It uses
|
|
|
28
28
|
WITH expression1 AS var1, expression2 AS var2
|
|
29
29
|
\`\`\`
|
|
30
30
|
|
|
31
|
-
2. **LOAD JSON FROM** - Load data from a URL
|
|
31
|
+
2. **LOAD JSON FROM** - Load data from a URL
|
|
32
32
|
\`\`\`
|
|
33
33
|
LOAD JSON FROM 'https://api.example.com/data' AS item
|
|
34
|
-
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
3. **CALL ... YIELD** - Call an async data provider function and yield its fields
|
|
37
|
+
\`\`\`
|
|
38
|
+
CALL myFunction(arg1, arg2) YIELD field1, field2, field3
|
|
35
39
|
\`\`\`
|
|
36
40
|
|
|
37
|
-
**IMPORTANT**: Async data providers (functions used
|
|
41
|
+
**IMPORTANT**: Async data providers (functions used with CALL) cannot be nested inside other function calls. If you need to pass data from one async provider to another, first load the data into a variable using collect(), then pass that variable:
|
|
38
42
|
\`\`\`
|
|
39
43
|
// WRONG - async providers cannot be nested:
|
|
40
|
-
//
|
|
44
|
+
// CALL table(mockProducts(5), 'Products') YIELD html
|
|
41
45
|
|
|
42
46
|
// CORRECT - collect data first, then pass to next provider:
|
|
43
|
-
|
|
44
|
-
WITH collect(
|
|
45
|
-
|
|
46
|
-
RETURN
|
|
47
|
+
CALL mockProducts(5) YIELD id, name, price
|
|
48
|
+
WITH collect({ id: id, name: name, price: price }) AS products
|
|
49
|
+
CALL table(products, 'Products') YIELD html
|
|
50
|
+
RETURN html
|
|
47
51
|
\`\`\`
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
4. **LOAD JSON FROM ... HEADERS ... POST** - Make HTTP requests with headers and body
|
|
50
54
|
\`\`\`
|
|
51
55
|
LOAD JSON FROM 'https://api.example.com/data'
|
|
52
56
|
HEADERS {
|
|
@@ -59,42 +63,38 @@ FlowQuery is a declarative query language for data processing pipelines. It uses
|
|
|
59
63
|
} AS response
|
|
60
64
|
\`\`\`
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
5. **UNWIND** - Expand arrays into individual rows
|
|
63
67
|
\`\`\`
|
|
64
68
|
UNWIND [1, 2, 3] AS number
|
|
65
69
|
UNWIND myArray AS item
|
|
66
70
|
UNWIND range(0, 10) AS index
|
|
67
71
|
\`\`\`
|
|
72
|
+
|
|
73
|
+
**IMPORTANT**: An UNWIND statement cannot be followed directly by a WHERE statement. If you need to filter after unwinding, use a WITH clause in between:
|
|
74
|
+
\`\`\`
|
|
75
|
+
// WRONG - UNWIND cannot be directly followed by WHERE:
|
|
76
|
+
// UNWIND items AS item
|
|
77
|
+
// WHERE item.active = true
|
|
78
|
+
|
|
79
|
+
// CORRECT - use WITH between UNWIND and WHERE:
|
|
80
|
+
UNWIND items AS item
|
|
81
|
+
WITH item
|
|
82
|
+
WHERE item.active = true
|
|
83
|
+
\`\`\`
|
|
68
84
|
|
|
69
|
-
|
|
85
|
+
6. **WHERE** - Filter results
|
|
70
86
|
\`\`\`
|
|
71
87
|
WHERE item.active = true
|
|
72
88
|
WHERE user.age > 18 AND user.name CONTAINS 'John'
|
|
73
89
|
\`\`\`
|
|
74
90
|
|
|
75
|
-
|
|
91
|
+
7. **RETURN** - Specify output columns
|
|
76
92
|
\`\`\`
|
|
77
93
|
RETURN item.name, item.value
|
|
78
94
|
RETURN item.name AS Name, item.price AS Price
|
|
79
95
|
RETURN * -- Return all fields
|
|
80
96
|
\`\`\`
|
|
81
97
|
|
|
82
|
-
7. **ORDER BY** - Sort results
|
|
83
|
-
\`\`\`
|
|
84
|
-
ORDER BY item.name ASC
|
|
85
|
-
ORDER BY item.price DESC, item.name ASC
|
|
86
|
-
\`\`\`
|
|
87
|
-
|
|
88
|
-
8. **LIMIT** - Limit number of results
|
|
89
|
-
\`\`\`
|
|
90
|
-
LIMIT 10
|
|
91
|
-
\`\`\`
|
|
92
|
-
|
|
93
|
-
9. **SKIP** - Skip a number of results
|
|
94
|
-
\`\`\`
|
|
95
|
-
SKIP 5
|
|
96
|
-
\`\`\`
|
|
97
|
-
|
|
98
98
|
### Built-in Functions
|
|
99
99
|
|
|
100
100
|
- **String Functions**: \`size()\`, \`substring()\`, \`trim()\`, \`toLower()\`, \`toUpper()\`, \`split()\`, \`join()\`, \`replace()\`, \`startsWith()\`, \`endsWith()\`, \`contains()\`
|
|
@@ -154,9 +154,12 @@ export class FlowQuerySystemPrompt {
|
|
|
154
154
|
* Format a parameter schema into a readable string.
|
|
155
155
|
*/
|
|
156
156
|
private static formatParameter(param: ParameterSchema): string {
|
|
157
|
-
const required = param.required ?
|
|
158
|
-
const defaultVal =
|
|
159
|
-
|
|
157
|
+
const required = param.required ? " (required)" : " (optional)";
|
|
158
|
+
const defaultVal =
|
|
159
|
+
param.default !== undefined ? `, default: ${JSON.stringify(param.default)}` : "";
|
|
160
|
+
const enumVals = param.enum
|
|
161
|
+
? `, values: [${param.enum.map((v) => JSON.stringify(v)).join(", ")}]`
|
|
162
|
+
: "";
|
|
160
163
|
return ` - \`${param.name}\`: ${param.type}${required}${defaultVal}${enumVals} - ${param.description}`;
|
|
161
164
|
}
|
|
162
165
|
|
|
@@ -165,18 +168,18 @@ export class FlowQuerySystemPrompt {
|
|
|
165
168
|
*/
|
|
166
169
|
private static formatOutput(output: OutputSchema): string {
|
|
167
170
|
let result = ` Returns: ${output.type} - ${output.description}`;
|
|
168
|
-
|
|
171
|
+
|
|
169
172
|
if (output.properties) {
|
|
170
|
-
result +=
|
|
173
|
+
result += "\n Output properties:";
|
|
171
174
|
for (const [key, prop] of Object.entries(output.properties)) {
|
|
172
175
|
result += `\n - \`${key}\`: ${prop.type} - ${prop.description}`;
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
|
-
|
|
178
|
+
|
|
176
179
|
if (output.example) {
|
|
177
180
|
result += `\n Example output: ${JSON.stringify(output.example, null, 2)}`;
|
|
178
181
|
}
|
|
179
|
-
|
|
182
|
+
|
|
180
183
|
return result;
|
|
181
184
|
}
|
|
182
185
|
|
|
@@ -185,38 +188,38 @@ export class FlowQuerySystemPrompt {
|
|
|
185
188
|
*/
|
|
186
189
|
private static formatPluginDocumentation(plugin: FunctionMetadata): string {
|
|
187
190
|
const lines: string[] = [];
|
|
188
|
-
|
|
191
|
+
|
|
189
192
|
lines.push(`### \`${plugin.name}\``);
|
|
190
193
|
lines.push(`**Description**: ${plugin.description}`);
|
|
191
|
-
|
|
194
|
+
|
|
192
195
|
if (plugin.category) {
|
|
193
196
|
lines.push(`**Category**: ${plugin.category}`);
|
|
194
197
|
}
|
|
195
|
-
|
|
198
|
+
|
|
196
199
|
if (plugin.parameters.length > 0) {
|
|
197
|
-
lines.push(
|
|
200
|
+
lines.push("\n**Parameters**:");
|
|
198
201
|
for (const param of plugin.parameters) {
|
|
199
202
|
lines.push(this.formatParameter(param));
|
|
200
203
|
}
|
|
201
204
|
} else {
|
|
202
|
-
lines.push(
|
|
205
|
+
lines.push("\n**Parameters**: None");
|
|
203
206
|
}
|
|
204
|
-
|
|
205
|
-
lines.push(
|
|
207
|
+
|
|
208
|
+
lines.push("\n**Output**:");
|
|
206
209
|
lines.push(this.formatOutput(plugin.output));
|
|
207
|
-
|
|
210
|
+
|
|
208
211
|
if (plugin.examples && plugin.examples.length > 0) {
|
|
209
|
-
lines.push(
|
|
212
|
+
lines.push("\n**Usage Examples**:");
|
|
210
213
|
for (const example of plugin.examples) {
|
|
211
214
|
lines.push(`\`\`\`\n${example}\n\`\`\``);
|
|
212
215
|
}
|
|
213
216
|
}
|
|
214
|
-
|
|
217
|
+
|
|
215
218
|
if (plugin.notes) {
|
|
216
219
|
lines.push(`\n**Notes**: ${plugin.notes}`);
|
|
217
220
|
}
|
|
218
|
-
|
|
219
|
-
return lines.join(
|
|
221
|
+
|
|
222
|
+
return lines.join("\n");
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
/**
|
|
@@ -224,33 +227,37 @@ export class FlowQuerySystemPrompt {
|
|
|
224
227
|
*/
|
|
225
228
|
private static generatePluginDocumentation(plugins: FunctionMetadata[]): string {
|
|
226
229
|
if (plugins.length === 0) {
|
|
227
|
-
return
|
|
230
|
+
return "No data loader plugins are currently available.";
|
|
228
231
|
}
|
|
229
|
-
|
|
232
|
+
|
|
230
233
|
const sections: string[] = [];
|
|
231
|
-
|
|
234
|
+
|
|
232
235
|
// Group plugins by category
|
|
233
236
|
const byCategory = new Map<string, FunctionMetadata[]>();
|
|
234
237
|
for (const plugin of plugins) {
|
|
235
|
-
const category = plugin.category ||
|
|
238
|
+
const category = plugin.category || "general";
|
|
236
239
|
if (!byCategory.has(category)) {
|
|
237
240
|
byCategory.set(category, []);
|
|
238
241
|
}
|
|
239
242
|
byCategory.get(category)!.push(plugin);
|
|
240
243
|
}
|
|
241
|
-
|
|
242
|
-
sections.push(
|
|
243
|
-
sections.push(
|
|
244
|
-
|
|
244
|
+
|
|
245
|
+
sections.push("## Available Data Loader Plugins\n");
|
|
246
|
+
sections.push(
|
|
247
|
+
"The following async data loader functions are available for use with `CALL ... YIELD`:\n"
|
|
248
|
+
);
|
|
249
|
+
|
|
245
250
|
for (const [category, categoryPlugins] of byCategory) {
|
|
246
|
-
sections.push(
|
|
251
|
+
sections.push(
|
|
252
|
+
`\n### Category: ${category.charAt(0).toUpperCase() + category.slice(1)}\n`
|
|
253
|
+
);
|
|
247
254
|
for (const plugin of categoryPlugins) {
|
|
248
255
|
sections.push(this.formatPluginDocumentation(plugin));
|
|
249
|
-
sections.push(
|
|
256
|
+
sections.push("---");
|
|
250
257
|
}
|
|
251
258
|
}
|
|
252
|
-
|
|
253
|
-
return sections.join(
|
|
259
|
+
|
|
260
|
+
return sections.join("\n");
|
|
254
261
|
}
|
|
255
262
|
|
|
256
263
|
/**
|
|
@@ -296,15 +303,15 @@ ${FLOWQUERY_LANGUAGE_REFERENCE}
|
|
|
296
303
|
|
|
297
304
|
${pluginDocs}
|
|
298
305
|
|
|
299
|
-
${additionalContext ? `## Additional Context\n\n${additionalContext}` :
|
|
306
|
+
${additionalContext ? `## Additional Context\n\n${additionalContext}` : ""}
|
|
300
307
|
|
|
301
308
|
## Example Response Format
|
|
302
309
|
|
|
303
310
|
**When a query is needed**:
|
|
304
311
|
\`\`\`flowquery
|
|
305
|
-
|
|
306
|
-
WHERE
|
|
307
|
-
RETURN
|
|
312
|
+
CALL pluginName(args) YIELD field1, field2, field3
|
|
313
|
+
WHERE field1 = 'value'
|
|
314
|
+
RETURN field1 AS Name, field2 AS Value
|
|
308
315
|
\`\`\`
|
|
309
316
|
|
|
310
317
|
**When no query is needed** (e.g., general questions about FlowQuery):
|
|
@@ -317,7 +324,7 @@ Now help the user with their request.`;
|
|
|
317
324
|
/**
|
|
318
325
|
* Generate the complete FlowQuery system prompt.
|
|
319
326
|
* Uses FlowQuery's introspection via functions() as the single source of truth.
|
|
320
|
-
*
|
|
327
|
+
*
|
|
321
328
|
* @param additionalContext - Optional additional context to include in the prompt
|
|
322
329
|
* @returns The complete system prompt string
|
|
323
330
|
*/
|
|
@@ -325,14 +332,14 @@ Now help the user with their request.`;
|
|
|
325
332
|
// Uses FlowQuery's introspection to get available async providers
|
|
326
333
|
const plugins = getAllPluginMetadata();
|
|
327
334
|
const pluginDocs = this.generatePluginDocumentation(plugins);
|
|
328
|
-
|
|
335
|
+
|
|
329
336
|
return this.buildSystemPrompt(pluginDocs, additionalContext);
|
|
330
337
|
}
|
|
331
338
|
|
|
332
339
|
/**
|
|
333
340
|
* Generate a system prompt for the interpretation phase.
|
|
334
341
|
* Used after FlowQuery execution to interpret results.
|
|
335
|
-
*
|
|
342
|
+
*
|
|
336
343
|
* @returns The interpretation system prompt string
|
|
337
344
|
*/
|
|
338
345
|
public static generateInterpretationPrompt(): string {
|
|
@@ -363,8 +370,8 @@ You are now receiving the execution results. Your job is to:
|
|
|
363
370
|
*/
|
|
364
371
|
public static getMinimalPrompt(): string {
|
|
365
372
|
const plugins = getAllPluginMetadata();
|
|
366
|
-
const pluginList = plugins.map(p => `- \`${p.name}\`: ${p.description}`).join(
|
|
367
|
-
|
|
373
|
+
const pluginList = plugins.map((p) => `- \`${p.name}\`: ${p.description}`).join("\n");
|
|
374
|
+
|
|
368
375
|
return `You are a FlowQuery assistant. Generate FlowQuery statements based on user requests.
|
|
369
376
|
|
|
370
377
|
Available data loader plugins:
|
|
@@ -379,7 +386,7 @@ Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
|
|
|
379
386
|
/**
|
|
380
387
|
* Generate the FlowQuery system prompt asynchronously using functions() introspection.
|
|
381
388
|
* This is the preferred method that uses FlowQuery's built-in introspection.
|
|
382
|
-
*
|
|
389
|
+
*
|
|
383
390
|
* @param additionalContext - Optional additional context to include in the prompt
|
|
384
391
|
* @returns Promise resolving to the complete system prompt string
|
|
385
392
|
*/
|
|
@@ -387,15 +394,19 @@ Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
|
|
|
387
394
|
// Use FlowQuery's functions() introspection to discover available loaders
|
|
388
395
|
const plugins = await getAvailableLoaders();
|
|
389
396
|
const pluginDocs = this.generatePluginDocumentation(plugins);
|
|
390
|
-
|
|
397
|
+
|
|
391
398
|
return this.buildSystemPrompt(pluginDocs, additionalContext);
|
|
392
399
|
}
|
|
393
400
|
}
|
|
394
401
|
|
|
395
402
|
// Export functions for backward compatibility
|
|
396
|
-
export const generateFlowQuerySystemPrompt =
|
|
397
|
-
|
|
398
|
-
export const
|
|
399
|
-
|
|
403
|
+
export const generateFlowQuerySystemPrompt =
|
|
404
|
+
FlowQuerySystemPrompt.generate.bind(FlowQuerySystemPrompt);
|
|
405
|
+
export const generateInterpretationPrompt =
|
|
406
|
+
FlowQuerySystemPrompt.generateInterpretationPrompt.bind(FlowQuerySystemPrompt);
|
|
407
|
+
export const getMinimalFlowQueryPrompt =
|
|
408
|
+
FlowQuerySystemPrompt.getMinimalPrompt.bind(FlowQuerySystemPrompt);
|
|
409
|
+
export const generateFlowQuerySystemPromptAsync =
|
|
410
|
+
FlowQuerySystemPrompt.generateAsync.bind(FlowQuerySystemPrompt);
|
|
400
411
|
|
|
401
412
|
export default FlowQuerySystemPrompt;
|
package/package.json
CHANGED
package/src/compute/runner.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import ASTNode from "../parsing/ast_node";
|
|
2
|
+
import Function from "../parsing/functions/function";
|
|
3
|
+
import { FunctionMetadata } from "../parsing/functions/function_metadata";
|
|
1
4
|
import Operation from "../parsing/operations/operation";
|
|
2
5
|
import Parser from "../parsing/parser";
|
|
3
|
-
import { FunctionMetadata } from "../parsing/functions/function_metadata";
|
|
4
|
-
import Function from "../parsing/functions/function";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Executes a FlowQuery statement and retrieves the results.
|
|
8
|
-
*
|
|
9
|
+
*
|
|
9
10
|
* The Runner class parses a FlowQuery statement into an AST and executes it,
|
|
10
11
|
* managing the execution flow from the first operation to the final return statement.
|
|
11
|
-
*
|
|
12
|
+
*
|
|
12
13
|
* @example
|
|
13
14
|
* ```typescript
|
|
14
15
|
* const runner = new Runner("WITH 1 as x RETURN x");
|
|
@@ -24,7 +25,11 @@ class Runner {
|
|
|
24
25
|
* List all registered functions with their metadata.
|
|
25
26
|
* Added dynamically in index.browser.ts / index.node.ts
|
|
26
27
|
*/
|
|
27
|
-
static listFunctions: (options?: {
|
|
28
|
+
static listFunctions: (options?: {
|
|
29
|
+
category?: string;
|
|
30
|
+
asyncOnly?: boolean;
|
|
31
|
+
syncOnly?: boolean;
|
|
32
|
+
}) => FunctionMetadata[];
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
35
|
* Get metadata for a specific function.
|
|
@@ -37,32 +42,32 @@ class Runner {
|
|
|
37
42
|
* Added dynamically in index.browser.ts / index.node.ts
|
|
38
43
|
*/
|
|
39
44
|
static Function: typeof Function;
|
|
40
|
-
|
|
45
|
+
|
|
41
46
|
/**
|
|
42
47
|
* Creates a new Runner instance and parses the FlowQuery statement.
|
|
43
|
-
*
|
|
48
|
+
*
|
|
44
49
|
* @param statement - The FlowQuery statement to execute
|
|
45
50
|
* @throws {Error} If the statement is null, empty, or contains syntax errors
|
|
46
51
|
*/
|
|
47
|
-
constructor(statement: string | null = null) {
|
|
48
|
-
if(statement === null || statement === "") {
|
|
49
|
-
throw new Error("
|
|
52
|
+
constructor(statement: string | null = null, ast: ASTNode | null = null) {
|
|
53
|
+
if ((statement === null || statement === "") && ast === null) {
|
|
54
|
+
throw new Error("Either statement or AST must be provided");
|
|
50
55
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
this.
|
|
54
|
-
this.last = ast.lastChild() as Operation;
|
|
56
|
+
const _ast = ast !== null ? ast : new Parser().parse(statement!);
|
|
57
|
+
this.first = _ast.firstChild() as Operation;
|
|
58
|
+
this.last = _ast.lastChild() as Operation;
|
|
55
59
|
}
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
/**
|
|
58
62
|
* Executes the parsed FlowQuery statement.
|
|
59
|
-
*
|
|
63
|
+
*
|
|
60
64
|
* @returns A promise that resolves when execution completes
|
|
61
65
|
* @throws {Error} If an error occurs during execution
|
|
62
66
|
*/
|
|
63
67
|
public async run(): Promise<void> {
|
|
64
68
|
return new Promise<void>(async (resolve, reject) => {
|
|
65
69
|
try {
|
|
70
|
+
await this.first.initialize();
|
|
66
71
|
await this.first.run();
|
|
67
72
|
await this.first.finish();
|
|
68
73
|
resolve();
|
|
@@ -71,10 +76,10 @@ class Runner {
|
|
|
71
76
|
}
|
|
72
77
|
});
|
|
73
78
|
}
|
|
74
|
-
|
|
79
|
+
|
|
75
80
|
/**
|
|
76
81
|
* Gets the results from the executed statement.
|
|
77
|
-
*
|
|
82
|
+
*
|
|
78
83
|
* @returns The results from the last operation (typically a RETURN statement)
|
|
79
84
|
*/
|
|
80
85
|
public get results(): any {
|
|
@@ -82,4 +87,4 @@ class Runner {
|
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
export default Runner;
|
|
90
|
+
export default Runner;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
class IndexEntry {
|
|
2
|
+
private _positions: number[];
|
|
3
|
+
private _index: number = -1;
|
|
4
|
+
|
|
5
|
+
constructor(positions: number[] = []) {
|
|
6
|
+
this._positions = positions;
|
|
7
|
+
}
|
|
8
|
+
public add(position: number): void {
|
|
9
|
+
this._positions.push(position);
|
|
10
|
+
}
|
|
11
|
+
public get position(): number {
|
|
12
|
+
return this._positions[this._index];
|
|
13
|
+
}
|
|
14
|
+
public reset(): void {
|
|
15
|
+
this._index = -1;
|
|
16
|
+
}
|
|
17
|
+
public next(): boolean {
|
|
18
|
+
if (this._index < this._positions.length - 1) {
|
|
19
|
+
this._index++;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
public clone(): IndexEntry {
|
|
25
|
+
return new IndexEntry([...this._positions]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Layer {
|
|
30
|
+
private _index: Map<string, IndexEntry> = new Map();
|
|
31
|
+
private _current: number = -1;
|
|
32
|
+
constructor(index: Map<string, IndexEntry>) {
|
|
33
|
+
this._index = index;
|
|
34
|
+
}
|
|
35
|
+
public get index(): Map<string, IndexEntry> {
|
|
36
|
+
return this._index;
|
|
37
|
+
}
|
|
38
|
+
public get current(): number {
|
|
39
|
+
return this._current;
|
|
40
|
+
}
|
|
41
|
+
public set current(value: number) {
|
|
42
|
+
this._current = value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class Data {
|
|
47
|
+
protected _records: Record<string, any>[] = [];
|
|
48
|
+
private _layers: Map<number, Layer> = new Map();
|
|
49
|
+
|
|
50
|
+
constructor(records: Record<string, any>[] = []) {
|
|
51
|
+
this._records = records;
|
|
52
|
+
this._layers.set(0, new Layer(new Map()));
|
|
53
|
+
}
|
|
54
|
+
protected _buildIndex(key: string, level: number = 0): void {
|
|
55
|
+
this.layer(level).index.clear();
|
|
56
|
+
this._records.forEach((record, idx) => {
|
|
57
|
+
if (record.hasOwnProperty(key)) {
|
|
58
|
+
if (!this.layer(level).index.has(record[key])) {
|
|
59
|
+
this.layer(level).index.set(record[key], new IndexEntry());
|
|
60
|
+
}
|
|
61
|
+
this.layer(level).index.get(record[key])!.add(idx);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
public layer(level: number = 0): Layer {
|
|
66
|
+
if (!this._layers.has(level)) {
|
|
67
|
+
const first = this._layers.get(0)!;
|
|
68
|
+
const cloned = new Map<string, IndexEntry>();
|
|
69
|
+
for (const [key, entry] of first.index) {
|
|
70
|
+
cloned.set(key, entry.clone());
|
|
71
|
+
}
|
|
72
|
+
this._layers.set(level, new Layer(cloned));
|
|
73
|
+
}
|
|
74
|
+
return this._layers.get(level)!;
|
|
75
|
+
}
|
|
76
|
+
protected _find(key: string, level: number = 0): boolean {
|
|
77
|
+
if (!this.layer(level).index.has(key)) {
|
|
78
|
+
this.layer(level).current = this._records.length; // Move to end
|
|
79
|
+
return false;
|
|
80
|
+
} else {
|
|
81
|
+
const entry = this.layer(level).index.get(key)!;
|
|
82
|
+
const more = entry.next();
|
|
83
|
+
if (!more) {
|
|
84
|
+
this.layer(level).current = this._records.length; // Move to end
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
this.layer(level).current = entry.position;
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
public reset(): void {
|
|
92
|
+
this.layer(0).current = -1;
|
|
93
|
+
for (const entry of this.layer(0).index.values()) {
|
|
94
|
+
entry.reset();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
public next(level: number = 0): boolean {
|
|
98
|
+
if (this.layer(level).current < this._records.length - 1) {
|
|
99
|
+
this.layer(level).current++;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
public current(level: number = 0): Record<string, any> | null {
|
|
105
|
+
if (this.layer(level).current < this._records.length) {
|
|
106
|
+
return this._records[this.layer(level).current];
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default Data;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import ASTNode from "../parsing/ast_node";
|
|
2
|
+
import Node from "./node";
|
|
3
|
+
import NodeData, { NodeRecord } from "./node_data";
|
|
4
|
+
import PhysicalNode from "./physical_node";
|
|
5
|
+
import PhysicalRelationship from "./physical_relationship";
|
|
6
|
+
import Relationship from "./relationship";
|
|
7
|
+
import RelationshipData, { RelationshipRecord } from "./relationship_data";
|
|
8
|
+
|
|
9
|
+
class Database {
|
|
10
|
+
private static instance: Database;
|
|
11
|
+
private static nodes: Map<string, PhysicalNode> = new Map();
|
|
12
|
+
private static relationships: Map<string, PhysicalRelationship> = new Map();
|
|
13
|
+
|
|
14
|
+
public static getInstance(): Database {
|
|
15
|
+
if (!Database.instance) {
|
|
16
|
+
Database.instance = new Database();
|
|
17
|
+
}
|
|
18
|
+
return Database.instance;
|
|
19
|
+
}
|
|
20
|
+
public addNode(node: Node, statement: ASTNode): void {
|
|
21
|
+
if (node.label === null) {
|
|
22
|
+
throw new Error("Node label is null");
|
|
23
|
+
}
|
|
24
|
+
const physical = new PhysicalNode(null, node.label);
|
|
25
|
+
physical.statement = statement;
|
|
26
|
+
Database.nodes.set(node.label, physical);
|
|
27
|
+
}
|
|
28
|
+
public getNode(node: Node): PhysicalNode | null {
|
|
29
|
+
return Database.nodes.get(node.label!) || null;
|
|
30
|
+
}
|
|
31
|
+
public addRelationship(relationship: Relationship, statement: ASTNode): void {
|
|
32
|
+
if (relationship.type === null) {
|
|
33
|
+
throw new Error("Relationship type is null");
|
|
34
|
+
}
|
|
35
|
+
const physical = new PhysicalRelationship(null, relationship.type);
|
|
36
|
+
physical.statement = statement;
|
|
37
|
+
Database.relationships.set(relationship.type, physical);
|
|
38
|
+
}
|
|
39
|
+
public getRelationship(relationship: Relationship): PhysicalRelationship | null {
|
|
40
|
+
return Database.relationships.get(relationship.type!) || null;
|
|
41
|
+
}
|
|
42
|
+
public async getData(element: Node | Relationship): Promise<NodeData | RelationshipData> {
|
|
43
|
+
if (element instanceof Node) {
|
|
44
|
+
const node = this.getNode(element);
|
|
45
|
+
if (node === null) {
|
|
46
|
+
throw new Error(`Physical node not found for label ${element.label}`);
|
|
47
|
+
}
|
|
48
|
+
const data = await node.data();
|
|
49
|
+
return new NodeData(data as NodeRecord[]);
|
|
50
|
+
} else if (element instanceof Relationship) {
|
|
51
|
+
const relationship = this.getRelationship(element);
|
|
52
|
+
if (relationship === null) {
|
|
53
|
+
throw new Error(`Physical relationship not found for type ${element.type}`);
|
|
54
|
+
}
|
|
55
|
+
const data = await relationship.data();
|
|
56
|
+
return new RelationshipData(data as RelationshipRecord[]);
|
|
57
|
+
} else {
|
|
58
|
+
throw new Error("Element is neither Node nor Relationship");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default Database;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Hops {
|
|
2
|
+
private _min: number = 0;
|
|
3
|
+
private _max: number = 1;
|
|
4
|
+
|
|
5
|
+
public set min(min: number) {
|
|
6
|
+
this._min = min;
|
|
7
|
+
}
|
|
8
|
+
public get min(): number {
|
|
9
|
+
return this._min;
|
|
10
|
+
}
|
|
11
|
+
public set max(max: number) {
|
|
12
|
+
this._max = max;
|
|
13
|
+
}
|
|
14
|
+
public get max(): number {
|
|
15
|
+
return this._max;
|
|
16
|
+
}
|
|
17
|
+
public multi(): boolean {
|
|
18
|
+
return this._max > 1 || this._max === -1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default Hops;
|