flowquery 1.0.46 → 1.0.48
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/dist/flowquery.min.js +1 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/parsing/data_structures/list_comprehension.d.ts +56 -0
- package/dist/parsing/data_structures/list_comprehension.d.ts.map +1 -0
- package/dist/parsing/data_structures/list_comprehension.js +102 -0
- package/dist/parsing/data_structures/list_comprehension.js.map +1 -0
- package/dist/parsing/parser.d.ts +18 -0
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +92 -0
- package/dist/parsing/parser.js.map +1 -1
- package/package.json +4 -1
- package/.editorconfig +0 -21
- package/.gitattributes +0 -3
- package/.github/workflows/npm-publish.yml +0 -32
- package/.github/workflows/python-publish.yml +0 -143
- package/.github/workflows/release.yml +0 -107
- package/.husky/pre-commit +0 -28
- package/.prettierrc +0 -22
- package/CODE_OF_CONDUCT.md +0 -10
- package/FlowQueryLogoIcon.png +0 -0
- package/SECURITY.md +0 -14
- package/SUPPORT.md +0 -13
- package/docs/flowquery.min.js +0 -1
- package/docs/index.html +0 -105
- package/flowquery-py/CONTRIBUTING.md +0 -127
- package/flowquery-py/README.md +0 -67
- package/flowquery-py/misc/data/test.json +0 -10
- package/flowquery-py/misc/data/users.json +0 -242
- package/flowquery-py/notebooks/TestFlowQuery.ipynb +0 -440
- package/flowquery-py/pyproject.toml +0 -121
- package/flowquery-py/setup_env.ps1 +0 -92
- package/flowquery-py/setup_env.sh +0 -87
- package/flowquery-py/src/__init__.py +0 -38
- package/flowquery-py/src/__main__.py +0 -10
- package/flowquery-py/src/compute/__init__.py +0 -6
- package/flowquery-py/src/compute/flowquery.py +0 -68
- package/flowquery-py/src/compute/runner.py +0 -64
- package/flowquery-py/src/extensibility.py +0 -52
- package/flowquery-py/src/graph/__init__.py +0 -31
- package/flowquery-py/src/graph/data.py +0 -136
- package/flowquery-py/src/graph/database.py +0 -141
- package/flowquery-py/src/graph/hops.py +0 -43
- package/flowquery-py/src/graph/node.py +0 -143
- package/flowquery-py/src/graph/node_data.py +0 -26
- package/flowquery-py/src/graph/node_reference.py +0 -50
- package/flowquery-py/src/graph/pattern.py +0 -115
- package/flowquery-py/src/graph/pattern_expression.py +0 -67
- package/flowquery-py/src/graph/patterns.py +0 -42
- package/flowquery-py/src/graph/physical_node.py +0 -41
- package/flowquery-py/src/graph/physical_relationship.py +0 -36
- package/flowquery-py/src/graph/relationship.py +0 -193
- package/flowquery-py/src/graph/relationship_data.py +0 -36
- package/flowquery-py/src/graph/relationship_match_collector.py +0 -85
- package/flowquery-py/src/graph/relationship_reference.py +0 -21
- package/flowquery-py/src/io/__init__.py +0 -5
- package/flowquery-py/src/io/command_line.py +0 -108
- package/flowquery-py/src/parsing/__init__.py +0 -17
- package/flowquery-py/src/parsing/alias.py +0 -20
- package/flowquery-py/src/parsing/alias_option.py +0 -11
- package/flowquery-py/src/parsing/ast_node.py +0 -147
- package/flowquery-py/src/parsing/base_parser.py +0 -84
- package/flowquery-py/src/parsing/components/__init__.py +0 -19
- package/flowquery-py/src/parsing/components/csv.py +0 -8
- package/flowquery-py/src/parsing/components/from_.py +0 -12
- package/flowquery-py/src/parsing/components/headers.py +0 -12
- package/flowquery-py/src/parsing/components/json.py +0 -8
- package/flowquery-py/src/parsing/components/null.py +0 -10
- package/flowquery-py/src/parsing/components/post.py +0 -8
- package/flowquery-py/src/parsing/components/text.py +0 -8
- package/flowquery-py/src/parsing/context.py +0 -50
- package/flowquery-py/src/parsing/data_structures/__init__.py +0 -15
- package/flowquery-py/src/parsing/data_structures/associative_array.py +0 -41
- package/flowquery-py/src/parsing/data_structures/json_array.py +0 -30
- package/flowquery-py/src/parsing/data_structures/key_value_pair.py +0 -38
- package/flowquery-py/src/parsing/data_structures/lookup.py +0 -51
- package/flowquery-py/src/parsing/data_structures/range_lookup.py +0 -42
- package/flowquery-py/src/parsing/expressions/__init__.py +0 -61
- package/flowquery-py/src/parsing/expressions/boolean.py +0 -20
- package/flowquery-py/src/parsing/expressions/expression.py +0 -141
- package/flowquery-py/src/parsing/expressions/expression_map.py +0 -26
- package/flowquery-py/src/parsing/expressions/f_string.py +0 -27
- package/flowquery-py/src/parsing/expressions/identifier.py +0 -21
- package/flowquery-py/src/parsing/expressions/number.py +0 -32
- package/flowquery-py/src/parsing/expressions/operator.py +0 -271
- package/flowquery-py/src/parsing/expressions/reference.py +0 -47
- package/flowquery-py/src/parsing/expressions/string.py +0 -27
- package/flowquery-py/src/parsing/functions/__init__.py +0 -127
- package/flowquery-py/src/parsing/functions/aggregate_function.py +0 -60
- package/flowquery-py/src/parsing/functions/async_function.py +0 -65
- package/flowquery-py/src/parsing/functions/avg.py +0 -55
- package/flowquery-py/src/parsing/functions/coalesce.py +0 -43
- package/flowquery-py/src/parsing/functions/collect.py +0 -75
- package/flowquery-py/src/parsing/functions/count.py +0 -79
- package/flowquery-py/src/parsing/functions/date_.py +0 -61
- package/flowquery-py/src/parsing/functions/datetime_.py +0 -62
- package/flowquery-py/src/parsing/functions/duration.py +0 -159
- package/flowquery-py/src/parsing/functions/element_id.py +0 -50
- package/flowquery-py/src/parsing/functions/function.py +0 -68
- package/flowquery-py/src/parsing/functions/function_factory.py +0 -170
- package/flowquery-py/src/parsing/functions/function_metadata.py +0 -148
- package/flowquery-py/src/parsing/functions/functions.py +0 -67
- package/flowquery-py/src/parsing/functions/head.py +0 -39
- package/flowquery-py/src/parsing/functions/id_.py +0 -49
- package/flowquery-py/src/parsing/functions/join.py +0 -49
- package/flowquery-py/src/parsing/functions/keys.py +0 -34
- package/flowquery-py/src/parsing/functions/last.py +0 -39
- package/flowquery-py/src/parsing/functions/localdatetime.py +0 -60
- package/flowquery-py/src/parsing/functions/localtime.py +0 -57
- package/flowquery-py/src/parsing/functions/max_.py +0 -49
- package/flowquery-py/src/parsing/functions/min_.py +0 -49
- package/flowquery-py/src/parsing/functions/nodes.py +0 -48
- package/flowquery-py/src/parsing/functions/predicate_function.py +0 -47
- package/flowquery-py/src/parsing/functions/predicate_sum.py +0 -49
- package/flowquery-py/src/parsing/functions/properties.py +0 -50
- package/flowquery-py/src/parsing/functions/rand.py +0 -28
- package/flowquery-py/src/parsing/functions/range_.py +0 -41
- package/flowquery-py/src/parsing/functions/reducer_element.py +0 -15
- package/flowquery-py/src/parsing/functions/relationships.py +0 -46
- package/flowquery-py/src/parsing/functions/replace.py +0 -39
- package/flowquery-py/src/parsing/functions/round_.py +0 -34
- package/flowquery-py/src/parsing/functions/schema.py +0 -40
- package/flowquery-py/src/parsing/functions/size.py +0 -34
- package/flowquery-py/src/parsing/functions/split.py +0 -54
- package/flowquery-py/src/parsing/functions/string_distance.py +0 -92
- package/flowquery-py/src/parsing/functions/stringify.py +0 -49
- package/flowquery-py/src/parsing/functions/substring.py +0 -76
- package/flowquery-py/src/parsing/functions/sum.py +0 -51
- package/flowquery-py/src/parsing/functions/tail.py +0 -37
- package/flowquery-py/src/parsing/functions/temporal_utils.py +0 -186
- package/flowquery-py/src/parsing/functions/time_.py +0 -57
- package/flowquery-py/src/parsing/functions/timestamp.py +0 -37
- package/flowquery-py/src/parsing/functions/to_float.py +0 -46
- package/flowquery-py/src/parsing/functions/to_integer.py +0 -46
- package/flowquery-py/src/parsing/functions/to_json.py +0 -35
- package/flowquery-py/src/parsing/functions/to_lower.py +0 -37
- package/flowquery-py/src/parsing/functions/to_string.py +0 -41
- package/flowquery-py/src/parsing/functions/trim.py +0 -37
- package/flowquery-py/src/parsing/functions/type_.py +0 -47
- package/flowquery-py/src/parsing/functions/value_holder.py +0 -24
- package/flowquery-py/src/parsing/logic/__init__.py +0 -15
- package/flowquery-py/src/parsing/logic/case.py +0 -28
- package/flowquery-py/src/parsing/logic/else_.py +0 -12
- package/flowquery-py/src/parsing/logic/end.py +0 -8
- package/flowquery-py/src/parsing/logic/then.py +0 -12
- package/flowquery-py/src/parsing/logic/when.py +0 -12
- package/flowquery-py/src/parsing/operations/__init__.py +0 -46
- package/flowquery-py/src/parsing/operations/aggregated_return.py +0 -25
- package/flowquery-py/src/parsing/operations/aggregated_with.py +0 -22
- package/flowquery-py/src/parsing/operations/call.py +0 -73
- package/flowquery-py/src/parsing/operations/create_node.py +0 -35
- package/flowquery-py/src/parsing/operations/create_relationship.py +0 -35
- package/flowquery-py/src/parsing/operations/delete_node.py +0 -29
- package/flowquery-py/src/parsing/operations/delete_relationship.py +0 -29
- package/flowquery-py/src/parsing/operations/group_by.py +0 -148
- package/flowquery-py/src/parsing/operations/limit.py +0 -33
- package/flowquery-py/src/parsing/operations/load.py +0 -148
- package/flowquery-py/src/parsing/operations/match.py +0 -52
- package/flowquery-py/src/parsing/operations/operation.py +0 -69
- package/flowquery-py/src/parsing/operations/order_by.py +0 -114
- package/flowquery-py/src/parsing/operations/projection.py +0 -21
- package/flowquery-py/src/parsing/operations/return_op.py +0 -88
- package/flowquery-py/src/parsing/operations/union.py +0 -115
- package/flowquery-py/src/parsing/operations/union_all.py +0 -17
- package/flowquery-py/src/parsing/operations/unwind.py +0 -42
- package/flowquery-py/src/parsing/operations/where.py +0 -43
- package/flowquery-py/src/parsing/operations/with_op.py +0 -18
- package/flowquery-py/src/parsing/parser.py +0 -1384
- package/flowquery-py/src/parsing/parser_state.py +0 -26
- package/flowquery-py/src/parsing/token_to_node.py +0 -109
- package/flowquery-py/src/tokenization/__init__.py +0 -23
- package/flowquery-py/src/tokenization/keyword.py +0 -54
- package/flowquery-py/src/tokenization/operator.py +0 -29
- package/flowquery-py/src/tokenization/string_walker.py +0 -158
- package/flowquery-py/src/tokenization/symbol.py +0 -19
- package/flowquery-py/src/tokenization/token.py +0 -693
- package/flowquery-py/src/tokenization/token_mapper.py +0 -53
- package/flowquery-py/src/tokenization/token_type.py +0 -21
- package/flowquery-py/src/tokenization/tokenizer.py +0 -214
- package/flowquery-py/src/tokenization/trie.py +0 -125
- package/flowquery-py/src/utils/__init__.py +0 -6
- package/flowquery-py/src/utils/object_utils.py +0 -20
- package/flowquery-py/src/utils/string_utils.py +0 -113
- package/flowquery-py/tests/__init__.py +0 -1
- package/flowquery-py/tests/compute/__init__.py +0 -1
- package/flowquery-py/tests/compute/test_runner.py +0 -4902
- package/flowquery-py/tests/graph/__init__.py +0 -1
- package/flowquery-py/tests/graph/test_create.py +0 -56
- package/flowquery-py/tests/graph/test_data.py +0 -73
- package/flowquery-py/tests/graph/test_match.py +0 -40
- package/flowquery-py/tests/parsing/__init__.py +0 -1
- package/flowquery-py/tests/parsing/test_context.py +0 -34
- package/flowquery-py/tests/parsing/test_expression.py +0 -248
- package/flowquery-py/tests/parsing/test_parser.py +0 -1237
- package/flowquery-py/tests/test_extensibility.py +0 -611
- package/flowquery-py/tests/tokenization/__init__.py +0 -1
- package/flowquery-py/tests/tokenization/test_token_mapper.py +0 -60
- package/flowquery-py/tests/tokenization/test_tokenizer.py +0 -198
- package/flowquery-py/tests/tokenization/test_trie.py +0 -30
- package/flowquery-vscode/.vscode-test.mjs +0 -5
- package/flowquery-vscode/.vscodeignore +0 -13
- package/flowquery-vscode/LICENSE +0 -21
- package/flowquery-vscode/README.md +0 -11
- package/flowquery-vscode/demo/FlowQueryVSCodeDemo.gif +0 -0
- package/flowquery-vscode/eslint.config.mjs +0 -25
- package/flowquery-vscode/extension.js +0 -508
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +0 -1
- package/flowquery-vscode/flowquery-worker.js +0 -66
- package/flowquery-vscode/images/FlowQueryLogoIcon.png +0 -0
- package/flowquery-vscode/jsconfig.json +0 -13
- package/flowquery-vscode/libs/page.css +0 -53
- package/flowquery-vscode/libs/table.css +0 -13
- package/flowquery-vscode/libs/tabs.css +0 -66
- package/flowquery-vscode/package-lock.json +0 -2917
- package/flowquery-vscode/package.json +0 -51
- package/flowquery-vscode/test/extension.test.js +0 -196
- package/flowquery-vscode/test/worker.test.js +0 -25
- package/flowquery-vscode/vsc-extension-quickstart.md +0 -42
- package/jest.config.js +0 -14
- package/misc/apps/RAG/README.md +0 -29
- package/misc/apps/RAG/data/chats.json +0 -302
- package/misc/apps/RAG/data/emails.json +0 -182
- package/misc/apps/RAG/data/events.json +0 -226
- package/misc/apps/RAG/data/files.json +0 -172
- package/misc/apps/RAG/data/users.json +0 -158
- package/misc/apps/RAG/jest.config.js +0 -21
- package/misc/apps/RAG/package.json +0 -48
- package/misc/apps/RAG/public/index.html +0 -18
- package/misc/apps/RAG/src/App.css +0 -42
- package/misc/apps/RAG/src/App.tsx +0 -50
- package/misc/apps/RAG/src/components/AdaptiveCardRenderer.css +0 -172
- package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +0 -380
- package/misc/apps/RAG/src/components/ApiKeySettings.tsx +0 -245
- package/misc/apps/RAG/src/components/ChatContainer.css +0 -67
- package/misc/apps/RAG/src/components/ChatContainer.tsx +0 -242
- package/misc/apps/RAG/src/components/ChatInput.css +0 -23
- package/misc/apps/RAG/src/components/ChatInput.tsx +0 -76
- package/misc/apps/RAG/src/components/ChatMessage.css +0 -160
- package/misc/apps/RAG/src/components/ChatMessage.tsx +0 -286
- package/misc/apps/RAG/src/components/FlowQueryAgent.ts +0 -708
- package/misc/apps/RAG/src/components/FlowQueryRunner.css +0 -113
- package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +0 -371
- package/misc/apps/RAG/src/components/index.ts +0 -28
- package/misc/apps/RAG/src/graph/index.ts +0 -19
- package/misc/apps/RAG/src/graph/initializeGraph.ts +0 -254
- package/misc/apps/RAG/src/index.tsx +0 -29
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +0 -327
- package/misc/apps/RAG/src/prompts/index.ts +0 -10
- package/misc/apps/RAG/src/tests/graph.test.ts +0 -35
- package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +0 -130
- package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +0 -208
- package/misc/apps/RAG/src/utils/Llm.ts +0 -248
- package/misc/apps/RAG/src/utils/index.ts +0 -12
- package/misc/apps/RAG/tsconfig.json +0 -22
- package/misc/apps/RAG/webpack.config.js +0 -43
- package/misc/apps/README.md +0 -1
- package/misc/queries/analyze_catfacts.cql +0 -75
- package/misc/queries/azure_openai_completions.cql +0 -13
- package/misc/queries/azure_openai_models.cql +0 -9
- package/misc/queries/mock_pipeline.cql +0 -84
- package/misc/queries/openai_completions.cql +0 -15
- package/misc/queries/openai_models.cql +0 -13
- package/misc/queries/test.cql +0 -6
- package/misc/queries/tool_inference.cql +0 -24
- package/misc/queries/wisdom.cql +0 -6
- package/misc/queries/wisdom_letter_histogram.cql +0 -8
- package/src/compute/flowquery.ts +0 -46
- package/src/compute/runner.ts +0 -66
- package/src/extensibility.ts +0 -45
- package/src/graph/data.ts +0 -130
- package/src/graph/database.ts +0 -143
- package/src/graph/hops.ts +0 -22
- package/src/graph/node.ts +0 -122
- package/src/graph/node_data.ts +0 -18
- package/src/graph/node_reference.ts +0 -38
- package/src/graph/pattern.ts +0 -110
- package/src/graph/pattern_expression.ts +0 -48
- package/src/graph/patterns.ts +0 -36
- package/src/graph/physical_node.ts +0 -23
- package/src/graph/physical_relationship.ts +0 -23
- package/src/graph/relationship.ts +0 -167
- package/src/graph/relationship_data.ts +0 -31
- package/src/graph/relationship_match_collector.ts +0 -64
- package/src/graph/relationship_reference.ts +0 -25
- package/src/index.browser.ts +0 -46
- package/src/index.node.ts +0 -55
- package/src/index.ts +0 -12
- package/src/io/command_line.ts +0 -74
- package/src/parsing/alias.ts +0 -23
- package/src/parsing/alias_option.ts +0 -5
- package/src/parsing/ast_node.ts +0 -153
- package/src/parsing/base_parser.ts +0 -98
- package/src/parsing/components/csv.ts +0 -9
- package/src/parsing/components/from.ts +0 -12
- package/src/parsing/components/headers.ts +0 -12
- package/src/parsing/components/json.ts +0 -9
- package/src/parsing/components/null.ts +0 -9
- package/src/parsing/components/post.ts +0 -9
- package/src/parsing/components/text.ts +0 -9
- package/src/parsing/context.ts +0 -54
- package/src/parsing/data_structures/associative_array.ts +0 -43
- package/src/parsing/data_structures/json_array.ts +0 -31
- package/src/parsing/data_structures/key_value_pair.ts +0 -37
- package/src/parsing/data_structures/lookup.ts +0 -44
- package/src/parsing/data_structures/range_lookup.ts +0 -36
- package/src/parsing/expressions/boolean.ts +0 -21
- package/src/parsing/expressions/expression.ts +0 -150
- package/src/parsing/expressions/expression_map.ts +0 -22
- package/src/parsing/expressions/f_string.ts +0 -26
- package/src/parsing/expressions/identifier.ts +0 -22
- package/src/parsing/expressions/number.ts +0 -40
- package/src/parsing/expressions/operator.ts +0 -354
- package/src/parsing/expressions/reference.ts +0 -45
- package/src/parsing/expressions/string.ts +0 -34
- package/src/parsing/functions/aggregate_function.ts +0 -58
- package/src/parsing/functions/async_function.ts +0 -64
- package/src/parsing/functions/avg.ts +0 -47
- package/src/parsing/functions/coalesce.ts +0 -49
- package/src/parsing/functions/collect.ts +0 -54
- package/src/parsing/functions/count.ts +0 -54
- package/src/parsing/functions/date.ts +0 -63
- package/src/parsing/functions/datetime.ts +0 -63
- package/src/parsing/functions/duration.ts +0 -143
- package/src/parsing/functions/element_id.ts +0 -51
- package/src/parsing/functions/function.ts +0 -60
- package/src/parsing/functions/function_factory.ts +0 -195
- package/src/parsing/functions/function_metadata.ts +0 -217
- package/src/parsing/functions/functions.ts +0 -70
- package/src/parsing/functions/head.ts +0 -42
- package/src/parsing/functions/id.ts +0 -51
- package/src/parsing/functions/join.ts +0 -40
- package/src/parsing/functions/keys.ts +0 -29
- package/src/parsing/functions/last.ts +0 -42
- package/src/parsing/functions/localdatetime.ts +0 -63
- package/src/parsing/functions/localtime.ts +0 -58
- package/src/parsing/functions/max.ts +0 -37
- package/src/parsing/functions/min.ts +0 -37
- package/src/parsing/functions/nodes.ts +0 -54
- package/src/parsing/functions/predicate_function.ts +0 -48
- package/src/parsing/functions/predicate_sum.ts +0 -47
- package/src/parsing/functions/properties.ts +0 -56
- package/src/parsing/functions/rand.ts +0 -21
- package/src/parsing/functions/range.ts +0 -37
- package/src/parsing/functions/reducer_element.ts +0 -10
- package/src/parsing/functions/relationships.ts +0 -52
- package/src/parsing/functions/replace.ts +0 -38
- package/src/parsing/functions/round.ts +0 -28
- package/src/parsing/functions/schema.ts +0 -39
- package/src/parsing/functions/size.ts +0 -28
- package/src/parsing/functions/split.ts +0 -45
- package/src/parsing/functions/string_distance.ts +0 -83
- package/src/parsing/functions/stringify.ts +0 -37
- package/src/parsing/functions/substring.ts +0 -68
- package/src/parsing/functions/sum.ts +0 -41
- package/src/parsing/functions/tail.ts +0 -39
- package/src/parsing/functions/temporal_utils.ts +0 -180
- package/src/parsing/functions/time.ts +0 -58
- package/src/parsing/functions/timestamp.ts +0 -37
- package/src/parsing/functions/to_float.ts +0 -50
- package/src/parsing/functions/to_integer.ts +0 -50
- package/src/parsing/functions/to_json.ts +0 -28
- package/src/parsing/functions/to_lower.ts +0 -28
- package/src/parsing/functions/to_string.ts +0 -32
- package/src/parsing/functions/trim.ts +0 -28
- package/src/parsing/functions/type.ts +0 -39
- package/src/parsing/functions/value_holder.ts +0 -13
- package/src/parsing/logic/case.ts +0 -26
- package/src/parsing/logic/else.ts +0 -12
- package/src/parsing/logic/end.ts +0 -9
- package/src/parsing/logic/then.ts +0 -12
- package/src/parsing/logic/when.ts +0 -12
- package/src/parsing/operations/aggregated_return.ts +0 -22
- package/src/parsing/operations/aggregated_with.ts +0 -18
- package/src/parsing/operations/call.ts +0 -69
- package/src/parsing/operations/create_node.ts +0 -39
- package/src/parsing/operations/create_relationship.ts +0 -38
- package/src/parsing/operations/delete_node.ts +0 -33
- package/src/parsing/operations/delete_relationship.ts +0 -32
- package/src/parsing/operations/group_by.ts +0 -137
- package/src/parsing/operations/limit.ts +0 -31
- package/src/parsing/operations/load.ts +0 -146
- package/src/parsing/operations/match.ts +0 -54
- package/src/parsing/operations/operation.ts +0 -69
- package/src/parsing/operations/order_by.ts +0 -126
- package/src/parsing/operations/projection.ts +0 -18
- package/src/parsing/operations/return.ts +0 -76
- package/src/parsing/operations/union.ts +0 -114
- package/src/parsing/operations/union_all.ts +0 -16
- package/src/parsing/operations/unwind.ts +0 -36
- package/src/parsing/operations/where.ts +0 -42
- package/src/parsing/operations/with.ts +0 -20
- package/src/parsing/parser.ts +0 -1641
- package/src/parsing/parser_state.ts +0 -25
- package/src/parsing/token_to_node.ts +0 -114
- package/src/tokenization/keyword.ts +0 -50
- package/src/tokenization/operator.ts +0 -25
- package/src/tokenization/string_walker.ts +0 -197
- package/src/tokenization/symbol.ts +0 -15
- package/src/tokenization/token.ts +0 -764
- package/src/tokenization/token_mapper.ts +0 -53
- package/src/tokenization/token_type.ts +0 -16
- package/src/tokenization/tokenizer.ts +0 -250
- package/src/tokenization/trie.ts +0 -117
- package/src/utils/object_utils.ts +0 -17
- package/src/utils/string_utils.ts +0 -114
- package/tests/compute/runner.test.ts +0 -4559
- package/tests/extensibility.test.ts +0 -643
- package/tests/graph/create.test.ts +0 -36
- package/tests/graph/data.test.ts +0 -58
- package/tests/graph/match.test.ts +0 -29
- package/tests/parsing/context.test.ts +0 -27
- package/tests/parsing/expression.test.ts +0 -303
- package/tests/parsing/parser.test.ts +0 -1327
- package/tests/tokenization/token_mapper.test.ts +0 -47
- package/tests/tokenization/tokenizer.test.ts +0 -191
- package/tests/tokenization/trie.test.ts +0 -20
- package/tsconfig.json +0 -19
- package/typedoc.json +0 -16
- package/vscode-settings.json.recommended +0 -16
- package/webpack.config.js +0 -26
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# FlowQuery Python Environment Setup Script for Linux/macOS
|
|
3
|
-
# This script creates a conda environment for FlowQuery development
|
|
4
|
-
|
|
5
|
-
echo "========================================"
|
|
6
|
-
echo "FlowQuery Python Environment Setup"
|
|
7
|
-
echo "========================================"
|
|
8
|
-
echo
|
|
9
|
-
|
|
10
|
-
# Check if conda is available
|
|
11
|
-
if ! command -v conda &> /dev/null; then
|
|
12
|
-
echo "ERROR: Conda is not installed or not in PATH."
|
|
13
|
-
echo "Please install Anaconda or Miniconda first."
|
|
14
|
-
exit 1
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Set environment name
|
|
18
|
-
ENV_NAME="flowquery"
|
|
19
|
-
|
|
20
|
-
# Get Python version from pyproject.toml
|
|
21
|
-
PYTHON_VERSION=$(grep -oP 'requires-python\s*=\s*">=\K[0-9.]+' pyproject.toml 2>/dev/null || echo "3.10")
|
|
22
|
-
echo "Using Python version: $PYTHON_VERSION"
|
|
23
|
-
|
|
24
|
-
# Check if environment already exists
|
|
25
|
-
if conda env list | grep -q "^${ENV_NAME} "; then
|
|
26
|
-
echo "Environment '${ENV_NAME}' already exists."
|
|
27
|
-
read -p "Do you want to recreate it? (y/n): " RECREATE
|
|
28
|
-
if [[ "$RECREATE" =~ ^[Yy]$ ]]; then
|
|
29
|
-
echo "Removing existing environment..."
|
|
30
|
-
conda env remove -n "$ENV_NAME" -y
|
|
31
|
-
else
|
|
32
|
-
echo "Keeping existing environment..."
|
|
33
|
-
echo
|
|
34
|
-
echo "========================================"
|
|
35
|
-
echo "Environment ready!"
|
|
36
|
-
echo "========================================"
|
|
37
|
-
echo
|
|
38
|
-
echo "To activate the environment, run:"
|
|
39
|
-
echo " conda activate $ENV_NAME"
|
|
40
|
-
echo
|
|
41
|
-
echo "To run tests:"
|
|
42
|
-
echo " pytest tests/"
|
|
43
|
-
echo
|
|
44
|
-
echo "To deactivate when done:"
|
|
45
|
-
echo " conda deactivate"
|
|
46
|
-
exit 0
|
|
47
|
-
fi
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# Create the environment
|
|
51
|
-
echo
|
|
52
|
-
echo "Creating conda environment '${ENV_NAME}' with Python ${PYTHON_VERSION}..."
|
|
53
|
-
conda create -n "$ENV_NAME" python="$PYTHON_VERSION" pip -y
|
|
54
|
-
|
|
55
|
-
if [ $? -ne 0 ]; then
|
|
56
|
-
echo
|
|
57
|
-
echo "ERROR: Failed to create conda environment."
|
|
58
|
-
exit 1
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
# Activate and install package in dev mode
|
|
62
|
-
echo
|
|
63
|
-
echo "Installing package in development mode..."
|
|
64
|
-
source "$(conda info --base)/etc/profile.d/conda.sh"
|
|
65
|
-
conda activate "$ENV_NAME"
|
|
66
|
-
pip install -e ".[dev]"
|
|
67
|
-
|
|
68
|
-
if [ $? -ne 0 ]; then
|
|
69
|
-
echo
|
|
70
|
-
echo "ERROR: Failed to install package."
|
|
71
|
-
exit 1
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
echo
|
|
75
|
-
echo "========================================"
|
|
76
|
-
echo "Environment created successfully!"
|
|
77
|
-
echo "========================================"
|
|
78
|
-
echo
|
|
79
|
-
echo "To activate the environment, run:"
|
|
80
|
-
echo " conda activate $ENV_NAME"
|
|
81
|
-
echo
|
|
82
|
-
echo "To run tests:"
|
|
83
|
-
echo " pytest tests/"
|
|
84
|
-
echo
|
|
85
|
-
echo "To deactivate when done:"
|
|
86
|
-
echo " conda deactivate"
|
|
87
|
-
echo
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
FlowQuery - A declarative query language for data processing pipelines.
|
|
3
|
-
|
|
4
|
-
This is the Python implementation of FlowQuery.
|
|
5
|
-
|
|
6
|
-
This module provides the core components for defining, parsing, and executing FlowQuery queries.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from .compute.flowquery import FlowQuery
|
|
10
|
-
from .compute.runner import Runner
|
|
11
|
-
from .io.command_line import CommandLine
|
|
12
|
-
from .parsing.functions.aggregate_function import AggregateFunction
|
|
13
|
-
from .parsing.functions.async_function import AsyncFunction
|
|
14
|
-
from .parsing.functions.function import Function
|
|
15
|
-
from .parsing.functions.function_metadata import (
|
|
16
|
-
FunctionCategory,
|
|
17
|
-
FunctionDef,
|
|
18
|
-
FunctionMetadata,
|
|
19
|
-
)
|
|
20
|
-
from .parsing.functions.predicate_function import PredicateFunction
|
|
21
|
-
from .parsing.functions.reducer_element import ReducerElement
|
|
22
|
-
from .parsing.parser import Parser
|
|
23
|
-
|
|
24
|
-
__all__ = [
|
|
25
|
-
"FlowQuery",
|
|
26
|
-
"Runner",
|
|
27
|
-
"CommandLine",
|
|
28
|
-
"Parser",
|
|
29
|
-
"Function",
|
|
30
|
-
"AggregateFunction",
|
|
31
|
-
"AsyncFunction",
|
|
32
|
-
"PredicateFunction",
|
|
33
|
-
"ReducerElement",
|
|
34
|
-
"FunctionDef",
|
|
35
|
-
"FunctionMetadata",
|
|
36
|
-
"FunctionCategory",
|
|
37
|
-
]
|
|
38
|
-
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"""FlowQuery public API surface.
|
|
2
|
-
|
|
3
|
-
Extends Runner with extensibility features such as function listing
|
|
4
|
-
and plugin registration, keeping the Runner focused on execution.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from typing import List, Optional, Type
|
|
8
|
-
|
|
9
|
-
from ..parsing.functions.function import Function
|
|
10
|
-
from ..parsing.functions.function_factory import FunctionFactory
|
|
11
|
-
from ..parsing.functions.function_metadata import (
|
|
12
|
-
FunctionMetadata,
|
|
13
|
-
get_function_metadata,
|
|
14
|
-
)
|
|
15
|
-
from .runner import Runner
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class FlowQuery(Runner):
|
|
19
|
-
"""FlowQuery is the public API surface for the FlowQuery library.
|
|
20
|
-
|
|
21
|
-
It extends Runner with convenience class methods for function
|
|
22
|
-
introspection and plugin registration.
|
|
23
|
-
|
|
24
|
-
Example:
|
|
25
|
-
fq = FlowQuery("WITH 1 as x RETURN x")
|
|
26
|
-
await fq.run()
|
|
27
|
-
print(fq.results) # [{'x': 1}]
|
|
28
|
-
|
|
29
|
-
# List all registered functions
|
|
30
|
-
functions = FlowQuery.list_functions()
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
#: Base Function class for creating custom plugin functions.
|
|
34
|
-
Function: Type[Function] = Function
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def list_functions(
|
|
38
|
-
category: Optional[str] = None,
|
|
39
|
-
async_only: bool = False,
|
|
40
|
-
sync_only: bool = False,
|
|
41
|
-
) -> List[FunctionMetadata]:
|
|
42
|
-
"""List all registered functions with their metadata.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
category: Optional category filter
|
|
46
|
-
async_only: If True, return only async functions
|
|
47
|
-
sync_only: If True, return only sync functions
|
|
48
|
-
|
|
49
|
-
Returns:
|
|
50
|
-
List of function metadata
|
|
51
|
-
"""
|
|
52
|
-
return FunctionFactory.list_functions(
|
|
53
|
-
category=category,
|
|
54
|
-
async_only=async_only,
|
|
55
|
-
sync_only=sync_only,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
@staticmethod
|
|
59
|
-
def get_function_metadata(name: str) -> Optional[FunctionMetadata]:
|
|
60
|
-
"""Get metadata for a specific function.
|
|
61
|
-
|
|
62
|
-
Args:
|
|
63
|
-
name: The function name
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
Function metadata or None
|
|
67
|
-
"""
|
|
68
|
-
return get_function_metadata(name.lower())
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"""Executes a FlowQuery statement and retrieves the results."""
|
|
2
|
-
|
|
3
|
-
from typing import Any, Dict, List, Optional
|
|
4
|
-
|
|
5
|
-
from ..parsing.ast_node import ASTNode
|
|
6
|
-
from ..parsing.operations.operation import Operation
|
|
7
|
-
from ..parsing.parser import Parser
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Runner:
|
|
11
|
-
"""Executes a FlowQuery statement and retrieves the results.
|
|
12
|
-
|
|
13
|
-
The Runner class parses a FlowQuery statement into an AST and executes it,
|
|
14
|
-
managing the execution flow from the first operation to the final return statement.
|
|
15
|
-
|
|
16
|
-
Example:
|
|
17
|
-
runner = Runner("WITH 1 as x RETURN x")
|
|
18
|
-
await runner.run()
|
|
19
|
-
print(runner.results) # [{ x: 1 }]
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def __init__(
|
|
23
|
-
self,
|
|
24
|
-
statement: Optional[str] = None,
|
|
25
|
-
ast: Optional[ASTNode] = None
|
|
26
|
-
):
|
|
27
|
-
"""Creates a new Runner instance and parses the FlowQuery statement.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
statement: The FlowQuery statement to execute
|
|
31
|
-
ast: An already-parsed AST (optional)
|
|
32
|
-
|
|
33
|
-
Raises:
|
|
34
|
-
ValueError: If neither statement nor AST is provided
|
|
35
|
-
"""
|
|
36
|
-
if (statement is None or statement == "") and ast is None:
|
|
37
|
-
raise ValueError("Either statement or AST must be provided")
|
|
38
|
-
|
|
39
|
-
_ast = ast if ast is not None else Parser().parse(statement or "")
|
|
40
|
-
first = _ast.first_child()
|
|
41
|
-
last = _ast.last_child()
|
|
42
|
-
if not isinstance(first, Operation) or not isinstance(last, Operation):
|
|
43
|
-
raise ValueError("AST must contain Operations")
|
|
44
|
-
self._first: Operation = first
|
|
45
|
-
self._last: Operation = last
|
|
46
|
-
|
|
47
|
-
async def run(self) -> None:
|
|
48
|
-
"""Executes the parsed FlowQuery statement.
|
|
49
|
-
|
|
50
|
-
Raises:
|
|
51
|
-
Exception: If an error occurs during execution
|
|
52
|
-
"""
|
|
53
|
-
await self._first.initialize()
|
|
54
|
-
await self._first.run()
|
|
55
|
-
await self._first.finish()
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def results(self) -> List[Dict[str, Any]]:
|
|
59
|
-
"""Gets the results from the executed statement.
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
The results from the last operation (typically a RETURN statement)
|
|
63
|
-
"""
|
|
64
|
-
return self._last.results
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"""FlowQuery Extensibility API
|
|
2
|
-
|
|
3
|
-
This module provides all the exports needed to create custom FlowQuery functions.
|
|
4
|
-
|
|
5
|
-
Example:
|
|
6
|
-
from flowquery.extensibility import Function, FunctionDef
|
|
7
|
-
|
|
8
|
-
@FunctionDef({
|
|
9
|
-
'description': "Converts a string to uppercase",
|
|
10
|
-
'category': "string",
|
|
11
|
-
'parameters': [{'name': "text", 'description': "String to convert", 'type': "string"}],
|
|
12
|
-
'output': {'description': "Uppercase string", 'type': "string"}
|
|
13
|
-
})
|
|
14
|
-
class UpperCase(Function):
|
|
15
|
-
def __init__(self):
|
|
16
|
-
super().__init__("uppercase")
|
|
17
|
-
self._expected_parameter_count = 1
|
|
18
|
-
|
|
19
|
-
def value(self) -> str:
|
|
20
|
-
return str(self.get_children()[0].value()).upper()
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
# Base function classes for creating custom functions
|
|
24
|
-
from .parsing.functions.aggregate_function import AggregateFunction
|
|
25
|
-
from .parsing.functions.async_function import AsyncFunction
|
|
26
|
-
from .parsing.functions.function import Function
|
|
27
|
-
|
|
28
|
-
# Decorator and metadata types for function registration
|
|
29
|
-
from .parsing.functions.function_metadata import (
|
|
30
|
-
FunctionCategory,
|
|
31
|
-
FunctionDef,
|
|
32
|
-
FunctionDefOptions,
|
|
33
|
-
FunctionMetadata,
|
|
34
|
-
OutputSchema,
|
|
35
|
-
ParameterSchema,
|
|
36
|
-
)
|
|
37
|
-
from .parsing.functions.predicate_function import PredicateFunction
|
|
38
|
-
from .parsing.functions.reducer_element import ReducerElement
|
|
39
|
-
|
|
40
|
-
__all__ = [
|
|
41
|
-
"Function",
|
|
42
|
-
"AggregateFunction",
|
|
43
|
-
"AsyncFunction",
|
|
44
|
-
"PredicateFunction",
|
|
45
|
-
"ReducerElement",
|
|
46
|
-
"FunctionDef",
|
|
47
|
-
"FunctionMetadata",
|
|
48
|
-
"FunctionDefOptions",
|
|
49
|
-
"ParameterSchema",
|
|
50
|
-
"OutputSchema",
|
|
51
|
-
"FunctionCategory",
|
|
52
|
-
]
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"""Graph module for FlowQuery."""
|
|
2
|
-
|
|
3
|
-
from .database import Database
|
|
4
|
-
from .hops import Hops
|
|
5
|
-
from .node import Node
|
|
6
|
-
from .node_data import NodeData
|
|
7
|
-
from .node_reference import NodeReference
|
|
8
|
-
from .pattern import Pattern
|
|
9
|
-
from .pattern_expression import PatternExpression
|
|
10
|
-
from .patterns import Patterns
|
|
11
|
-
from .physical_node import PhysicalNode
|
|
12
|
-
from .physical_relationship import PhysicalRelationship
|
|
13
|
-
from .relationship import Relationship
|
|
14
|
-
from .relationship_data import RelationshipData
|
|
15
|
-
from .relationship_reference import RelationshipReference
|
|
16
|
-
|
|
17
|
-
__all__ = [
|
|
18
|
-
"Node",
|
|
19
|
-
"Relationship",
|
|
20
|
-
"Pattern",
|
|
21
|
-
"Patterns",
|
|
22
|
-
"PatternExpression",
|
|
23
|
-
"Database",
|
|
24
|
-
"Hops",
|
|
25
|
-
"NodeData",
|
|
26
|
-
"NodeReference",
|
|
27
|
-
"RelationshipData",
|
|
28
|
-
"RelationshipReference",
|
|
29
|
-
"PhysicalNode",
|
|
30
|
-
"PhysicalRelationship",
|
|
31
|
-
]
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"""Data class for graph record iteration and indexing."""
|
|
2
|
-
|
|
3
|
-
from typing import Any, Dict, List, Optional
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class IndexEntry:
|
|
7
|
-
"""Index entry for tracking positions of records with a specific key value."""
|
|
8
|
-
|
|
9
|
-
def __init__(self, positions: Optional[List[int]] = None):
|
|
10
|
-
self._positions: List[int] = positions if positions is not None else []
|
|
11
|
-
self._index: int = -1
|
|
12
|
-
|
|
13
|
-
def add(self, position: int) -> None:
|
|
14
|
-
"""Add a position to the index entry."""
|
|
15
|
-
self._positions.append(position)
|
|
16
|
-
|
|
17
|
-
@property
|
|
18
|
-
def position(self) -> int:
|
|
19
|
-
"""Get the current position."""
|
|
20
|
-
return self._positions[self._index]
|
|
21
|
-
|
|
22
|
-
def reset(self) -> None:
|
|
23
|
-
"""Reset the index to the beginning."""
|
|
24
|
-
self._index = -1
|
|
25
|
-
|
|
26
|
-
def next(self) -> bool:
|
|
27
|
-
"""Move to the next position. Returns True if successful."""
|
|
28
|
-
if self._index < len(self._positions) - 1:
|
|
29
|
-
self._index += 1
|
|
30
|
-
return True
|
|
31
|
-
return False
|
|
32
|
-
|
|
33
|
-
def clone(self) -> "IndexEntry":
|
|
34
|
-
"""Create a copy of this index entry."""
|
|
35
|
-
return IndexEntry(list(self._positions))
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class Layer:
|
|
39
|
-
"""Layer for managing index state at a specific level."""
|
|
40
|
-
|
|
41
|
-
def __init__(self, indexes: Dict[str, Dict[str, IndexEntry]]):
|
|
42
|
-
self._indexes: Dict[str, Dict[str, IndexEntry]] = indexes
|
|
43
|
-
self._current: int = -1
|
|
44
|
-
|
|
45
|
-
def index(self, name: str) -> Dict[str, IndexEntry]:
|
|
46
|
-
"""Get or create an index by name."""
|
|
47
|
-
if name not in self._indexes:
|
|
48
|
-
self._indexes[name] = {}
|
|
49
|
-
return self._indexes[name]
|
|
50
|
-
|
|
51
|
-
@property
|
|
52
|
-
def indexes(self) -> Dict[str, Dict[str, IndexEntry]]:
|
|
53
|
-
"""Get all indexes."""
|
|
54
|
-
return self._indexes
|
|
55
|
-
|
|
56
|
-
@property
|
|
57
|
-
def current(self) -> int:
|
|
58
|
-
"""Get the current position."""
|
|
59
|
-
return self._current
|
|
60
|
-
|
|
61
|
-
@current.setter
|
|
62
|
-
def current(self, value: int) -> None:
|
|
63
|
-
"""Set the current position."""
|
|
64
|
-
self._current = value
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class Data:
|
|
68
|
-
"""Base class for graph data with record iteration and indexing."""
|
|
69
|
-
|
|
70
|
-
def __init__(self, records: Optional[List[Dict[str, Any]]] = None):
|
|
71
|
-
self._records: List[Dict[str, Any]] = records if records is not None else []
|
|
72
|
-
self._layers: Dict[int, Layer] = {0: Layer({})}
|
|
73
|
-
|
|
74
|
-
def _build_index(self, key: str, level: int = 0) -> None:
|
|
75
|
-
"""Build an index for the given key at the specified level."""
|
|
76
|
-
idx = self.layer(level).index(key)
|
|
77
|
-
idx.clear()
|
|
78
|
-
for i, record in enumerate(self._records):
|
|
79
|
-
if key in record:
|
|
80
|
-
if record[key] not in idx:
|
|
81
|
-
idx[record[key]] = IndexEntry()
|
|
82
|
-
idx[record[key]].add(i)
|
|
83
|
-
|
|
84
|
-
def layer(self, level: int = 0) -> Layer:
|
|
85
|
-
"""Get or create a layer at the specified level."""
|
|
86
|
-
if level not in self._layers:
|
|
87
|
-
first = self._layers[0]
|
|
88
|
-
cloned_indexes = {}
|
|
89
|
-
for name, index_map in first.indexes.items():
|
|
90
|
-
cloned_map = {}
|
|
91
|
-
for key, entry in index_map.items():
|
|
92
|
-
cloned_map[key] = entry.clone()
|
|
93
|
-
cloned_indexes[name] = cloned_map
|
|
94
|
-
self._layers[level] = Layer(cloned_indexes)
|
|
95
|
-
return self._layers[level]
|
|
96
|
-
|
|
97
|
-
def _find(self, key: str, level: int = 0, index_name: Optional[str] = None) -> bool:
|
|
98
|
-
"""Find the next record with the given key value."""
|
|
99
|
-
idx: Optional[Dict[str, IndexEntry]] = None
|
|
100
|
-
if index_name:
|
|
101
|
-
idx = self.layer(level).index(index_name)
|
|
102
|
-
else:
|
|
103
|
-
indexes = self.layer(level).indexes
|
|
104
|
-
idx = next(iter(indexes.values())) if indexes else None
|
|
105
|
-
if not idx or key not in idx:
|
|
106
|
-
self.layer(level).current = len(self._records) # Move to end
|
|
107
|
-
return False
|
|
108
|
-
else:
|
|
109
|
-
entry = idx[key]
|
|
110
|
-
more = entry.next()
|
|
111
|
-
if not more:
|
|
112
|
-
self.layer(level).current = len(self._records) # Move to end
|
|
113
|
-
return False
|
|
114
|
-
self.layer(level).current = entry.position
|
|
115
|
-
return True
|
|
116
|
-
|
|
117
|
-
def reset(self) -> None:
|
|
118
|
-
"""Reset iteration to the beginning."""
|
|
119
|
-
for layer in self._layers.values():
|
|
120
|
-
layer.current = -1
|
|
121
|
-
for index_map in layer.indexes.values():
|
|
122
|
-
for entry in index_map.values():
|
|
123
|
-
entry.reset()
|
|
124
|
-
|
|
125
|
-
def next(self, level: int = 0) -> bool:
|
|
126
|
-
"""Move to the next record. Returns True if successful."""
|
|
127
|
-
if self.layer(level).current < len(self._records) - 1:
|
|
128
|
-
self.layer(level).current += 1
|
|
129
|
-
return True
|
|
130
|
-
return False
|
|
131
|
-
|
|
132
|
-
def current(self, level: int = 0) -> Optional[Dict[str, Any]]:
|
|
133
|
-
"""Get the current record."""
|
|
134
|
-
if self.layer(level).current < len(self._records):
|
|
135
|
-
return self._records[self.layer(level).current]
|
|
136
|
-
return None
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"""Graph database for FlowQuery."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any, AsyncIterator, Dict, List, Optional, Union
|
|
6
|
-
|
|
7
|
-
from ..parsing.ast_node import ASTNode
|
|
8
|
-
from .node import Node
|
|
9
|
-
from .node_data import NodeData
|
|
10
|
-
from .physical_node import PhysicalNode
|
|
11
|
-
from .physical_relationship import PhysicalRelationship
|
|
12
|
-
from .relationship import Relationship
|
|
13
|
-
from .relationship_data import RelationshipData
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Database:
|
|
17
|
-
"""Singleton database for storing graph data."""
|
|
18
|
-
|
|
19
|
-
_instance: Optional['Database'] = None
|
|
20
|
-
_nodes: Dict[str, 'PhysicalNode'] = {}
|
|
21
|
-
_relationships: Dict[str, 'PhysicalRelationship'] = {}
|
|
22
|
-
|
|
23
|
-
def __init__(self) -> None:
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
@classmethod
|
|
27
|
-
def get_instance(cls) -> 'Database':
|
|
28
|
-
if cls._instance is None:
|
|
29
|
-
cls._instance = Database()
|
|
30
|
-
return cls._instance
|
|
31
|
-
|
|
32
|
-
def add_node(self, node: 'Node', statement: ASTNode) -> None:
|
|
33
|
-
"""Adds a node to the database."""
|
|
34
|
-
if node.label is None:
|
|
35
|
-
raise ValueError("Node label is null")
|
|
36
|
-
physical = PhysicalNode(None, node.label)
|
|
37
|
-
physical.statement = statement
|
|
38
|
-
Database._nodes[node.label] = physical
|
|
39
|
-
|
|
40
|
-
def remove_node(self, node: 'Node') -> None:
|
|
41
|
-
"""Removes a node from the database."""
|
|
42
|
-
if node.label is None:
|
|
43
|
-
raise ValueError("Node label is null")
|
|
44
|
-
Database._nodes.pop(node.label, None)
|
|
45
|
-
|
|
46
|
-
def get_node(self, node: 'Node') -> Optional['PhysicalNode']:
|
|
47
|
-
"""Gets a node from the database."""
|
|
48
|
-
return Database._nodes.get(node.label) if node.label else None
|
|
49
|
-
|
|
50
|
-
def add_relationship(self, relationship: 'Relationship', statement: ASTNode) -> None:
|
|
51
|
-
"""Adds a relationship to the database."""
|
|
52
|
-
if relationship.type is None:
|
|
53
|
-
raise ValueError("Relationship type is null")
|
|
54
|
-
physical = PhysicalRelationship()
|
|
55
|
-
physical.type = relationship.type
|
|
56
|
-
physical.statement = statement
|
|
57
|
-
if relationship.source is not None:
|
|
58
|
-
physical.source = relationship.source
|
|
59
|
-
if relationship.target is not None:
|
|
60
|
-
physical.target = relationship.target
|
|
61
|
-
Database._relationships[relationship.type] = physical
|
|
62
|
-
|
|
63
|
-
def remove_relationship(self, relationship: 'Relationship') -> None:
|
|
64
|
-
"""Removes a relationship from the database."""
|
|
65
|
-
if relationship.type is None:
|
|
66
|
-
raise ValueError("Relationship type is null")
|
|
67
|
-
Database._relationships.pop(relationship.type, None)
|
|
68
|
-
|
|
69
|
-
def get_relationship(self, relationship: 'Relationship') -> Optional['PhysicalRelationship']:
|
|
70
|
-
"""Gets a relationship from the database."""
|
|
71
|
-
return Database._relationships.get(relationship.type) if relationship.type else None
|
|
72
|
-
|
|
73
|
-
def get_relationships(self, relationship: 'Relationship') -> list['PhysicalRelationship']:
|
|
74
|
-
"""Gets multiple physical relationships for ORed types."""
|
|
75
|
-
result = []
|
|
76
|
-
for rel_type in relationship.types:
|
|
77
|
-
physical = Database._relationships.get(rel_type)
|
|
78
|
-
if physical:
|
|
79
|
-
result.append(physical)
|
|
80
|
-
return result
|
|
81
|
-
|
|
82
|
-
async def schema(self) -> List[Dict[str, Any]]:
|
|
83
|
-
"""Returns the graph schema with node/relationship labels and sample data."""
|
|
84
|
-
return [item async for item in self._schema()]
|
|
85
|
-
|
|
86
|
-
async def _schema(self) -> AsyncIterator[Dict[str, Any]]:
|
|
87
|
-
"""Async generator for graph schema with node/relationship labels and sample data."""
|
|
88
|
-
for label, physical_node in Database._nodes.items():
|
|
89
|
-
records = await physical_node.data()
|
|
90
|
-
entry: Dict[str, Any] = {"kind": "Node", "label": label}
|
|
91
|
-
if records:
|
|
92
|
-
sample = {k: v for k, v in records[0].items() if k != "id"}
|
|
93
|
-
properties = list(sample.keys())
|
|
94
|
-
if properties:
|
|
95
|
-
entry["properties"] = properties
|
|
96
|
-
entry["sample"] = sample
|
|
97
|
-
yield entry
|
|
98
|
-
|
|
99
|
-
for rel_type, physical_rel in Database._relationships.items():
|
|
100
|
-
records = await physical_rel.data()
|
|
101
|
-
entry_rel: Dict[str, Any] = {
|
|
102
|
-
"kind": "Relationship",
|
|
103
|
-
"type": rel_type,
|
|
104
|
-
"from_label": physical_rel.source.label if physical_rel.source else None,
|
|
105
|
-
"to_label": physical_rel.target.label if physical_rel.target else None,
|
|
106
|
-
}
|
|
107
|
-
if records:
|
|
108
|
-
sample = {k: v for k, v in records[0].items() if k not in ("left_id", "right_id")}
|
|
109
|
-
properties = list(sample.keys())
|
|
110
|
-
if properties:
|
|
111
|
-
entry_rel["properties"] = properties
|
|
112
|
-
entry_rel["sample"] = sample
|
|
113
|
-
yield entry_rel
|
|
114
|
-
|
|
115
|
-
async def get_data(self, element: Union['Node', 'Relationship']) -> Union['NodeData', 'RelationshipData']:
|
|
116
|
-
"""Gets data for a node or relationship."""
|
|
117
|
-
if isinstance(element, Node):
|
|
118
|
-
node = self.get_node(element)
|
|
119
|
-
if node is None:
|
|
120
|
-
raise ValueError(f"Physical node not found for label {element.label}")
|
|
121
|
-
data = await node.data()
|
|
122
|
-
return NodeData(data)
|
|
123
|
-
elif isinstance(element, Relationship):
|
|
124
|
-
if len(element.types) > 1:
|
|
125
|
-
physicals = self.get_relationships(element)
|
|
126
|
-
if not physicals:
|
|
127
|
-
raise ValueError(f"No physical relationships found for types {', '.join(element.types)}")
|
|
128
|
-
all_records = []
|
|
129
|
-
for i, physical in enumerate(physicals):
|
|
130
|
-
records = await physical.data()
|
|
131
|
-
type_name = element.types[i]
|
|
132
|
-
for record in records:
|
|
133
|
-
all_records.append({**record, "_type": type_name})
|
|
134
|
-
return RelationshipData(all_records)
|
|
135
|
-
relationship = self.get_relationship(element)
|
|
136
|
-
if relationship is None:
|
|
137
|
-
raise ValueError(f"Physical relationship not found for type {element.type}")
|
|
138
|
-
data = await relationship.data()
|
|
139
|
-
return RelationshipData(data)
|
|
140
|
-
else:
|
|
141
|
-
raise ValueError("Element is neither Node nor Relationship")
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"""Hops specification for variable-length relationships."""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Hops:
|
|
8
|
-
"""Specifies the number of hops for a relationship pattern."""
|
|
9
|
-
|
|
10
|
-
def __init__(self, min_hops: Optional[int] = None, max_hops: Optional[int] = None):
|
|
11
|
-
# Default min=0, max=1 (matching TypeScript implementation)
|
|
12
|
-
if min_hops is None:
|
|
13
|
-
self._min: int = 0
|
|
14
|
-
else:
|
|
15
|
-
self._min = min_hops
|
|
16
|
-
if max_hops is None:
|
|
17
|
-
self._max: int = 1
|
|
18
|
-
else:
|
|
19
|
-
self._max = max_hops
|
|
20
|
-
|
|
21
|
-
@property
|
|
22
|
-
def min(self) -> int:
|
|
23
|
-
return self._min
|
|
24
|
-
|
|
25
|
-
@min.setter
|
|
26
|
-
def min(self, value: int) -> None:
|
|
27
|
-
self._min = value
|
|
28
|
-
|
|
29
|
-
@property
|
|
30
|
-
def max(self) -> int:
|
|
31
|
-
return self._max
|
|
32
|
-
|
|
33
|
-
@max.setter
|
|
34
|
-
def max(self, value: int) -> None:
|
|
35
|
-
self._max = value
|
|
36
|
-
|
|
37
|
-
def multi(self) -> bool:
|
|
38
|
-
"""Returns True if this represents a variable-length relationship."""
|
|
39
|
-
return self._max > 1 or self._max == -1 or self._max == sys.maxsize
|
|
40
|
-
|
|
41
|
-
def unbounded(self) -> bool:
|
|
42
|
-
"""Returns True if the max is unbounded."""
|
|
43
|
-
return self._max == sys.maxsize
|