datahike-browser-tests 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +405 -0
- package/.circleci/scripts/gen_ci.clj +194 -0
- package/.cirrus.yml +60 -0
- package/.clj-kondo/babashka/sci/config.edn +1 -0
- package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
- package/.clj-kondo/config.edn +95 -0
- package/.dir-locals.el +2 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
- package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
- package/.github/ISSUE_TEMPLATE/config.yml +6 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/workflows/native-image.yml +84 -0
- package/LICENSE +203 -0
- package/README.md +273 -0
- package/bb/deps.edn +9 -0
- package/bb/resources/github-fingerprints +3 -0
- package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
- package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
- package/bb/resources/native-image-tests/run-native-image-tests +74 -0
- package/bb/resources/native-image-tests/run-python-tests +22 -0
- package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
- package/bb/resources/native-image-tests/testconfig.edn +5 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/bb/resources/template/pom.xml +22 -0
- package/bb/src/tools/build.clj +132 -0
- package/bb/src/tools/clj_kondo.clj +32 -0
- package/bb/src/tools/deploy.clj +26 -0
- package/bb/src/tools/examples.clj +19 -0
- package/bb/src/tools/npm.clj +100 -0
- package/bb/src/tools/python.clj +14 -0
- package/bb/src/tools/release.clj +94 -0
- package/bb/src/tools/test.clj +148 -0
- package/bb/src/tools/version.clj +47 -0
- package/bb.edn +269 -0
- package/benchmark/src/benchmark/cli.clj +195 -0
- package/benchmark/src/benchmark/compare.clj +157 -0
- package/benchmark/src/benchmark/config.clj +316 -0
- package/benchmark/src/benchmark/measure.clj +187 -0
- package/benchmark/src/benchmark/store.clj +190 -0
- package/benchmark/test/benchmark/measure_test.clj +156 -0
- package/build.clj +30 -0
- package/config.edn +49 -0
- package/deps.edn +138 -0
- package/dev/sandbox.clj +82 -0
- package/dev/sandbox.cljs +127 -0
- package/dev/sandbox_benchmarks.clj +27 -0
- package/dev/sandbox_client.clj +87 -0
- package/dev/sandbox_transact_bench.clj +109 -0
- package/dev/user.clj +79 -0
- package/doc/README.md +96 -0
- package/doc/adl/README.md +6 -0
- package/doc/adl/adr-000-adr.org +28 -0
- package/doc/adl/adr-001-attribute-references.org +15 -0
- package/doc/adl/adr-002-build-tooling.org +54 -0
- package/doc/adl/adr-003-db-meta-data.md +52 -0
- package/doc/adl/adr-004-github-flow.md +40 -0
- package/doc/adl/adr-XYZ-template.md +30 -0
- package/doc/adl/index.org +3 -0
- package/doc/assets/datahike-logo.svg +3 -0
- package/doc/assets/datahiking-invoice.org +85 -0
- package/doc/assets/hhtree2.png +0 -0
- package/doc/assets/network_topology.svg +624 -0
- package/doc/assets/perf.png +0 -0
- package/doc/assets/schema_mindmap.mm +132 -0
- package/doc/assets/schema_mindmap.svg +970 -0
- package/doc/assets/temporal_index.mm +74 -0
- package/doc/backend-development.md +78 -0
- package/doc/bb-pod.md +89 -0
- package/doc/benchmarking.md +360 -0
- package/doc/bindings/edn-conversion.md +383 -0
- package/doc/cli.md +162 -0
- package/doc/cljdoc.edn +27 -0
- package/doc/cljs-support.md +133 -0
- package/doc/config.md +406 -0
- package/doc/contributing.md +114 -0
- package/doc/datalog-vs-sql.md +210 -0
- package/doc/datomic_differences.md +109 -0
- package/doc/development/pull-api-ns.md +186 -0
- package/doc/development/pull-frame-state-diagram.jpg +0 -0
- package/doc/distributed.md +566 -0
- package/doc/entity_spec.md +92 -0
- package/doc/gc.md +273 -0
- package/doc/java-api.md +808 -0
- package/doc/javascript-api.md +421 -0
- package/doc/libdatahike.md +86 -0
- package/doc/logging_and_error_handling.md +43 -0
- package/doc/norms.md +66 -0
- package/doc/schema-migration.md +85 -0
- package/doc/schema.md +287 -0
- package/doc/storage-backends.md +363 -0
- package/doc/store-id-refactoring.md +596 -0
- package/doc/time_variance.md +325 -0
- package/doc/unstructured.md +167 -0
- package/doc/versioning.md +261 -0
- package/examples/basic/README.md +19 -0
- package/examples/basic/deps.edn +6 -0
- package/examples/basic/docker-compose.yml +13 -0
- package/examples/basic/src/examples/core.clj +60 -0
- package/examples/basic/src/examples/schema.clj +155 -0
- package/examples/basic/src/examples/store.clj +60 -0
- package/examples/basic/src/examples/time_travel.clj +185 -0
- package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
- package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/examples/java/README.md +162 -0
- package/examples/java/pom.xml +62 -0
- package/examples/java/src/main/java/examples/QuickStart.java +115 -0
- package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
- package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
- package/flake.lock +27 -0
- package/flake.nix +27 -0
- package/http-server/datahike/http/middleware.clj +75 -0
- package/http-server/datahike/http/server.clj +269 -0
- package/java/src/datahike/java/Database.java +274 -0
- package/java/src/datahike/java/Datahike.java +281 -0
- package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
- package/java/src/datahike/java/DatahikeTest.java +370 -0
- package/java/src/datahike/java/EDN.java +170 -0
- package/java/src/datahike/java/IEntity.java +11 -0
- package/java/src/datahike/java/Keywords.java +161 -0
- package/java/src/datahike/java/SchemaFlexibility.java +52 -0
- package/java/src/datahike/java/Util.java +219 -0
- package/karma.conf.js +19 -0
- package/libdatahike/compile-cpp +7 -0
- package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
- package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
- package/libdatahike/src/test_cpp.cpp +61 -0
- package/npm-package/PUBLISHING.md +140 -0
- package/npm-package/README.md +226 -0
- package/npm-package/package.template.json +34 -0
- package/npm-package/test-isomorphic.ts +281 -0
- package/npm-package/test.js +557 -0
- package/npm-package/typescript-test.ts +70 -0
- package/package.json +16 -0
- package/pydatahike/README.md +569 -0
- package/pydatahike/pyproject.toml +91 -0
- package/pydatahike/setup.py +42 -0
- package/pydatahike/src/datahike/__init__.py +134 -0
- package/pydatahike/src/datahike/_native.py +250 -0
- package/pydatahike/src/datahike/_version.py +2 -0
- package/pydatahike/src/datahike/database.py +722 -0
- package/pydatahike/src/datahike/edn.py +311 -0
- package/pydatahike/src/datahike/py.typed +0 -0
- package/pydatahike/tests/conftest.py +17 -0
- package/pydatahike/tests/test_basic.py +170 -0
- package/pydatahike/tests/test_database.py +51 -0
- package/pydatahike/tests/test_edn_conversion.py +299 -0
- package/pydatahike/tests/test_query.py +99 -0
- package/pydatahike/tests/test_schema.py +55 -0
- package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
- package/resources/example_server.edn +4 -0
- package/shadow-cljs.edn +56 -0
- package/src/data_readers.clj +7 -0
- package/src/datahike/api/impl.cljc +176 -0
- package/src/datahike/api/specification.cljc +633 -0
- package/src/datahike/api/types.cljc +261 -0
- package/src/datahike/api.cljc +41 -0
- package/src/datahike/array.cljc +99 -0
- package/src/datahike/cli.clj +166 -0
- package/src/datahike/cljs.cljs +6 -0
- package/src/datahike/codegen/cli.clj +406 -0
- package/src/datahike/codegen/clj_kondo.clj +291 -0
- package/src/datahike/codegen/java.clj +403 -0
- package/src/datahike/codegen/naming.cljc +33 -0
- package/src/datahike/codegen/native.clj +559 -0
- package/src/datahike/codegen/pod.clj +488 -0
- package/src/datahike/codegen/python.clj +838 -0
- package/src/datahike/codegen/report.clj +55 -0
- package/src/datahike/codegen/typescript.clj +262 -0
- package/src/datahike/codegen/validation.clj +145 -0
- package/src/datahike/config.cljc +294 -0
- package/src/datahike/connections.cljc +16 -0
- package/src/datahike/connector.cljc +265 -0
- package/src/datahike/constants.cljc +142 -0
- package/src/datahike/core.cljc +297 -0
- package/src/datahike/datom.cljc +459 -0
- package/src/datahike/db/interface.cljc +119 -0
- package/src/datahike/db/search.cljc +305 -0
- package/src/datahike/db/transaction.cljc +937 -0
- package/src/datahike/db/utils.cljc +338 -0
- package/src/datahike/db.cljc +956 -0
- package/src/datahike/experimental/unstructured.cljc +126 -0
- package/src/datahike/experimental/versioning.cljc +172 -0
- package/src/datahike/externs.js +31 -0
- package/src/datahike/gc.cljc +69 -0
- package/src/datahike/http/client.clj +188 -0
- package/src/datahike/http/writer.clj +79 -0
- package/src/datahike/impl/entity.cljc +218 -0
- package/src/datahike/index/interface.cljc +93 -0
- package/src/datahike/index/persistent_set.cljc +469 -0
- package/src/datahike/index/utils.cljc +44 -0
- package/src/datahike/index.cljc +32 -0
- package/src/datahike/js/api.cljs +172 -0
- package/src/datahike/js/api_macros.clj +22 -0
- package/src/datahike/js.cljs +163 -0
- package/src/datahike/json.cljc +209 -0
- package/src/datahike/lru.cljc +146 -0
- package/src/datahike/migrate.clj +39 -0
- package/src/datahike/norm/norm.clj +245 -0
- package/src/datahike/online_gc.cljc +252 -0
- package/src/datahike/pod.clj +155 -0
- package/src/datahike/pull_api.cljc +325 -0
- package/src/datahike/query.cljc +1945 -0
- package/src/datahike/query_stats.cljc +88 -0
- package/src/datahike/readers.cljc +62 -0
- package/src/datahike/remote.cljc +218 -0
- package/src/datahike/schema.cljc +228 -0
- package/src/datahike/schema_cache.cljc +42 -0
- package/src/datahike/spec.cljc +101 -0
- package/src/datahike/store.cljc +80 -0
- package/src/datahike/tools.cljc +308 -0
- package/src/datahike/transit.cljc +80 -0
- package/src/datahike/writer.cljc +239 -0
- package/src/datahike/writing.cljc +362 -0
- package/src/deps.cljs +1 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
- package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
- package/test/datahike/integration_test/config_record_file_test.clj +14 -0
- package/test/datahike/integration_test/config_record_test.clj +14 -0
- package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
- package/test/datahike/integration_test/return_map_test.clj +62 -0
- package/test/datahike/integration_test.cljc +67 -0
- package/test/datahike/norm/norm_test.clj +124 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
- package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/test/api_test.cljc +895 -0
- package/test/datahike/test/array_test.cljc +40 -0
- package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
- package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
- package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
- package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
- package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
- package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
- package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
- package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
- package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
- package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
- package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
- package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
- package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
- package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
- package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
- package/test/datahike/test/attribute_refs/utils.cljc +128 -0
- package/test/datahike/test/cache_test.cljc +38 -0
- package/test/datahike/test/components_test.cljc +92 -0
- package/test/datahike/test/config_test.cljc +158 -0
- package/test/datahike/test/core_test.cljc +105 -0
- package/test/datahike/test/datom_test.cljc +44 -0
- package/test/datahike/test/db_test.cljc +54 -0
- package/test/datahike/test/entity_spec_test.cljc +159 -0
- package/test/datahike/test/entity_test.cljc +103 -0
- package/test/datahike/test/explode_test.cljc +143 -0
- package/test/datahike/test/filter_test.cljc +75 -0
- package/test/datahike/test/gc_test.cljc +159 -0
- package/test/datahike/test/http/server_test.clj +192 -0
- package/test/datahike/test/http/writer_test.clj +86 -0
- package/test/datahike/test/ident_test.cljc +32 -0
- package/test/datahike/test/index_test.cljc +345 -0
- package/test/datahike/test/insert.cljc +125 -0
- package/test/datahike/test/java_bindings_test.clj +6 -0
- package/test/datahike/test/listen_test.cljc +41 -0
- package/test/datahike/test/lookup_refs_test.cljc +266 -0
- package/test/datahike/test/lru_test.cljc +27 -0
- package/test/datahike/test/migrate_test.clj +297 -0
- package/test/datahike/test/model/core.cljc +376 -0
- package/test/datahike/test/model/invariant.cljc +142 -0
- package/test/datahike/test/model/rng.cljc +82 -0
- package/test/datahike/test/model_test.clj +217 -0
- package/test/datahike/test/nodejs_test.cljs +262 -0
- package/test/datahike/test/online_gc_test.cljc +475 -0
- package/test/datahike/test/pod_test.clj +369 -0
- package/test/datahike/test/pull_api_test.cljc +474 -0
- package/test/datahike/test/purge_test.cljc +144 -0
- package/test/datahike/test/query_aggregates_test.cljc +101 -0
- package/test/datahike/test/query_find_specs_test.cljc +52 -0
- package/test/datahike/test/query_fns_test.cljc +523 -0
- package/test/datahike/test/query_interop_test.cljc +47 -0
- package/test/datahike/test/query_not_test.cljc +189 -0
- package/test/datahike/test/query_or_test.cljc +158 -0
- package/test/datahike/test/query_pull_test.cljc +147 -0
- package/test/datahike/test/query_rules_test.cljc +248 -0
- package/test/datahike/test/query_stats_test.cljc +218 -0
- package/test/datahike/test/query_test.cljc +984 -0
- package/test/datahike/test/schema_test.cljc +424 -0
- package/test/datahike/test/specification_test.cljc +30 -0
- package/test/datahike/test/store_test.cljc +78 -0
- package/test/datahike/test/stress_test.cljc +57 -0
- package/test/datahike/test/time_variance_test.cljc +518 -0
- package/test/datahike/test/tools_test.clj +134 -0
- package/test/datahike/test/transact_test.cljc +518 -0
- package/test/datahike/test/tuples_test.cljc +564 -0
- package/test/datahike/test/unstructured_test.cljc +291 -0
- package/test/datahike/test/upsert_impl_test.cljc +205 -0
- package/test/datahike/test/upsert_test.cljc +363 -0
- package/test/datahike/test/utils.cljc +110 -0
- package/test/datahike/test/validation_test.cljc +48 -0
- package/test/datahike/test/versioning_test.cljc +56 -0
- package/test/datahike/test.cljc +66 -0
- package/tests.edn +24 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
(ns datahike.pod
|
|
2
|
+
"Babashka pod interface for Datahike.
|
|
3
|
+
|
|
4
|
+
This namespace provides the pod protocol implementation that allows
|
|
5
|
+
Datahike to be used from Babashka scripts.
|
|
6
|
+
|
|
7
|
+
The pod manages connections and database snapshots via ID-based references,
|
|
8
|
+
allowing immutable db values to be cached and released explicitly.
|
|
9
|
+
|
|
10
|
+
Functions are generated at compile-time from the API specification via
|
|
11
|
+
datahike.codegen.pod macros."
|
|
12
|
+
(:refer-clojure :exclude [read read-string])
|
|
13
|
+
(:require [bencode.core :as bencode]
|
|
14
|
+
[clojure.java.io :as io]
|
|
15
|
+
[cognitect.transit :as transit]
|
|
16
|
+
[datahike.api :as d]
|
|
17
|
+
[datahike.writing :as writing]
|
|
18
|
+
[datahike.codegen.pod :as codegen])
|
|
19
|
+
(:import [java.io PushbackInputStream]))
|
|
20
|
+
|
|
21
|
+
(set! *warn-on-reflection* true)
|
|
22
|
+
|
|
23
|
+
;; =============================================================================
|
|
24
|
+
;; I/O Infrastructure
|
|
25
|
+
;; =============================================================================
|
|
26
|
+
|
|
27
|
+
(def stdin (PushbackInputStream. System/in))
|
|
28
|
+
(def stdout System/out)
|
|
29
|
+
(def stderr System/err)
|
|
30
|
+
|
|
31
|
+
(def debug? false)
|
|
32
|
+
|
|
33
|
+
(defn debug [& strs]
|
|
34
|
+
(when debug?
|
|
35
|
+
(binding [*out* (io/writer System/err)]
|
|
36
|
+
(apply prn strs))))
|
|
37
|
+
|
|
38
|
+
(defn write
|
|
39
|
+
([v] (write stdout v))
|
|
40
|
+
([stream v]
|
|
41
|
+
(debug :writing v)
|
|
42
|
+
(bencode/write-bencode stream v)
|
|
43
|
+
(flush)))
|
|
44
|
+
|
|
45
|
+
(defn write-err
|
|
46
|
+
([v] (write stderr v))
|
|
47
|
+
([stream v]
|
|
48
|
+
(debug :writing v)
|
|
49
|
+
(bencode/write-bencode stream v)
|
|
50
|
+
(flush)))
|
|
51
|
+
|
|
52
|
+
(defn read-string [^"[B" v]
|
|
53
|
+
(String. v))
|
|
54
|
+
|
|
55
|
+
(defn read [stream]
|
|
56
|
+
(bencode/read-bencode stream))
|
|
57
|
+
|
|
58
|
+
(defn read-transit [^String v]
|
|
59
|
+
(transit/read
|
|
60
|
+
(transit/reader
|
|
61
|
+
(java.io.ByteArrayInputStream. (.getBytes v "utf-8"))
|
|
62
|
+
:json)))
|
|
63
|
+
|
|
64
|
+
(defn write-transit [v]
|
|
65
|
+
(let [baos (java.io.ByteArrayOutputStream.)]
|
|
66
|
+
(transit/write (transit/writer baos :json) v)
|
|
67
|
+
(.toString baos "utf-8")))
|
|
68
|
+
|
|
69
|
+
;; =============================================================================
|
|
70
|
+
;; Generated Pod Runtime (atoms, helpers)
|
|
71
|
+
;; =============================================================================
|
|
72
|
+
|
|
73
|
+
(codegen/defpod-runtime)
|
|
74
|
+
|
|
75
|
+
;; =============================================================================
|
|
76
|
+
;; Generated Pod Functions
|
|
77
|
+
;; =============================================================================
|
|
78
|
+
|
|
79
|
+
(codegen/defpod-functions)
|
|
80
|
+
|
|
81
|
+
;; =============================================================================
|
|
82
|
+
;; Generated Pod Protocol Maps
|
|
83
|
+
;; =============================================================================
|
|
84
|
+
|
|
85
|
+
(codegen/defpod-publics)
|
|
86
|
+
|
|
87
|
+
(codegen/defpod-describe-map)
|
|
88
|
+
|
|
89
|
+
(defn lookup
|
|
90
|
+
"Look up a function by name."
|
|
91
|
+
[var]
|
|
92
|
+
(get publics (symbol (name var))))
|
|
93
|
+
|
|
94
|
+
;; =============================================================================
|
|
95
|
+
;; Pod Runner
|
|
96
|
+
;; =============================================================================
|
|
97
|
+
|
|
98
|
+
(defn run-pod
|
|
99
|
+
"Main pod event loop."
|
|
100
|
+
[_args]
|
|
101
|
+
(loop []
|
|
102
|
+
(let [message (try (read stdin)
|
|
103
|
+
(catch java.io.EOFException _
|
|
104
|
+
::EOF))]
|
|
105
|
+
(when-not (identical? ::EOF message)
|
|
106
|
+
(let [op (get message "op")
|
|
107
|
+
op (read-string op)
|
|
108
|
+
op (keyword op)
|
|
109
|
+
id (some-> (get message "id")
|
|
110
|
+
read-string)
|
|
111
|
+
id (or id "unknown")]
|
|
112
|
+
(case op
|
|
113
|
+
:describe (do (write {"format" "transit+json"
|
|
114
|
+
"namespaces" [{"name" "datahike.pod"
|
|
115
|
+
"vars" describe-map}]
|
|
116
|
+
"id" id
|
|
117
|
+
"ops" {"shutdown" {}}})
|
|
118
|
+
(recur))
|
|
119
|
+
:invoke (do (try
|
|
120
|
+
(let [var (-> (get message "var")
|
|
121
|
+
read-string
|
|
122
|
+
symbol)
|
|
123
|
+
args (get message "args")
|
|
124
|
+
args (read-string args)
|
|
125
|
+
args (read-transit args)]
|
|
126
|
+
(if-let [f (lookup var)]
|
|
127
|
+
(do (debug f)
|
|
128
|
+
(debug args)
|
|
129
|
+
(let [result (apply f args)
|
|
130
|
+
_ (debug result)
|
|
131
|
+
value (write-transit result)
|
|
132
|
+
reply {"value" value
|
|
133
|
+
"id" id
|
|
134
|
+
"status" ["done"]}]
|
|
135
|
+
(write stdout reply)))
|
|
136
|
+
(throw (ex-info (str "Var not found: " var) {}))))
|
|
137
|
+
(catch Throwable e
|
|
138
|
+
(debug e)
|
|
139
|
+
(let [reply {"ex-message" (ex-message e)
|
|
140
|
+
"ex-data" (write-transit
|
|
141
|
+
(-> (ex-data e)
|
|
142
|
+
(update :argument-type str)
|
|
143
|
+
(assoc :type (str (class e)))))
|
|
144
|
+
"id" id
|
|
145
|
+
"status" ["done" "error"]}]
|
|
146
|
+
(write stdout reply))))
|
|
147
|
+
(recur))
|
|
148
|
+
:shutdown (System/exit 0)
|
|
149
|
+
(do
|
|
150
|
+
(let [reply {"ex-message" "Unknown op"
|
|
151
|
+
"ex-data" (pr-str {:op op})
|
|
152
|
+
"id" id
|
|
153
|
+
"status" ["done" "error"]}]
|
|
154
|
+
(write stdout reply))
|
|
155
|
+
(recur))))))))
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
(ns ^:no-doc datahike.pull-api
|
|
2
|
+
(:require
|
|
3
|
+
[datahike.db.utils :as dbu]
|
|
4
|
+
[datahike.db.interface :as dbi]
|
|
5
|
+
[datalog.parser.pull :as dpp #?@(:cljs [:refer [PullSpec]])])
|
|
6
|
+
#?(:clj
|
|
7
|
+
(:import
|
|
8
|
+
[datahike.datom Datom]
|
|
9
|
+
[datalog.parser.pull PullSpec])))
|
|
10
|
+
|
|
11
|
+
(defn- into!
|
|
12
|
+
[transient-coll items]
|
|
13
|
+
(reduce conj! transient-coll items))
|
|
14
|
+
|
|
15
|
+
(def ^:private ^:const +default-limit+ 1000)
|
|
16
|
+
|
|
17
|
+
(defn- initial-frame
|
|
18
|
+
"Creates an empty pattern frame according to pattern information."
|
|
19
|
+
[pattern eids multi?]
|
|
20
|
+
{:state :pattern
|
|
21
|
+
:pattern pattern
|
|
22
|
+
:wildcard? (:wildcard? pattern)
|
|
23
|
+
:specs (-> pattern :attrs seq)
|
|
24
|
+
:results (transient [])
|
|
25
|
+
:kvps (transient {})
|
|
26
|
+
:eids eids
|
|
27
|
+
:multi? multi?
|
|
28
|
+
:recursion {:depth {} :seen #{}}})
|
|
29
|
+
|
|
30
|
+
(defn subpattern-frame
|
|
31
|
+
"Returns frame specific for given attribute"
|
|
32
|
+
[pattern eids multi? attr]
|
|
33
|
+
(assoc (initial-frame pattern eids multi?) :attr attr))
|
|
34
|
+
|
|
35
|
+
(defn reset-frame
|
|
36
|
+
"Recalculate frame attributes from frame pattern and transfer end results to frame-specific result section"
|
|
37
|
+
[frame eids kvps]
|
|
38
|
+
(let [pattern (:pattern frame)]
|
|
39
|
+
(assoc frame
|
|
40
|
+
:eids eids
|
|
41
|
+
:specs (seq (:attrs pattern))
|
|
42
|
+
:wildcard? (:wildcard? pattern)
|
|
43
|
+
:kvps (transient {})
|
|
44
|
+
:results (cond-> (:results frame)
|
|
45
|
+
(seq kvps) (conj! kvps)))))
|
|
46
|
+
|
|
47
|
+
(defn push-recursion
|
|
48
|
+
"Push newly processed entity and increase recursion depth."
|
|
49
|
+
[rec attr eid]
|
|
50
|
+
(let [{:keys [depth seen]} rec]
|
|
51
|
+
(assoc rec
|
|
52
|
+
:depth (update depth attr (fnil inc 0))
|
|
53
|
+
:seen (conj seen eid))))
|
|
54
|
+
|
|
55
|
+
(defn seen-eid?
|
|
56
|
+
[frame eid]
|
|
57
|
+
(-> frame
|
|
58
|
+
(get-in [:recursion :seen] #{})
|
|
59
|
+
(contains? eid)))
|
|
60
|
+
|
|
61
|
+
(defn pull-seen-eid
|
|
62
|
+
"Add eid to result set if entity already seen. Else return nil."
|
|
63
|
+
[frame frames eid]
|
|
64
|
+
(when (seen-eid? frame eid)
|
|
65
|
+
(conj frames (update frame :results conj! {:db/id eid}))))
|
|
66
|
+
|
|
67
|
+
(defn single-frame-result
|
|
68
|
+
[key frame]
|
|
69
|
+
(some-> (:kvps frame) persistent! (get key)))
|
|
70
|
+
|
|
71
|
+
(defn recursion-result [frame]
|
|
72
|
+
(single-frame-result ::recursion frame))
|
|
73
|
+
|
|
74
|
+
(defn recursion-frame
|
|
75
|
+
[parent eid]
|
|
76
|
+
(let [attr (:attr parent)
|
|
77
|
+
rec (push-recursion (:recursion parent) attr eid)]
|
|
78
|
+
(assoc (subpattern-frame (:pattern parent) [eid] false ::recursion)
|
|
79
|
+
:recursion rec)))
|
|
80
|
+
|
|
81
|
+
(defn pull-recursion-frame
|
|
82
|
+
"Processes recursion for one entity ID or collects results.
|
|
83
|
+
Replaces current frame with
|
|
84
|
+
- one frame with remaining entiy IDs and
|
|
85
|
+
- one subpattern frame"
|
|
86
|
+
[db [frame & frames]]
|
|
87
|
+
(if-let [eids (seq (:eids frame))]
|
|
88
|
+
(let [frame (reset-frame frame (rest eids) (recursion-result frame))
|
|
89
|
+
eid (first eids)]
|
|
90
|
+
(or (pull-seen-eid frame frames eid)
|
|
91
|
+
(conj frames frame (recursion-frame frame eid))))
|
|
92
|
+
(let [kvps (recursion-result frame)
|
|
93
|
+
results (cond-> (:results frame)
|
|
94
|
+
(seq kvps) (conj! kvps))]
|
|
95
|
+
(conj frames (assoc frame :state :done :results results)))))
|
|
96
|
+
|
|
97
|
+
(defn recurse-attr
|
|
98
|
+
"Adds recursion frame to frame set if maximum recursion depth not reached"
|
|
99
|
+
[db attr multi? eids eid parent frames]
|
|
100
|
+
(let [{:keys [recursion pattern]} parent
|
|
101
|
+
depth (-> recursion (get :depth) (get attr 0))]
|
|
102
|
+
(if (-> pattern :attrs (get attr) :recursion (= depth))
|
|
103
|
+
(conj frames parent)
|
|
104
|
+
(pull-recursion-frame
|
|
105
|
+
db
|
|
106
|
+
(conj frames parent
|
|
107
|
+
{:state :recursion :pattern pattern
|
|
108
|
+
:attr attr :multi? multi? :eids eids
|
|
109
|
+
:recursion recursion
|
|
110
|
+
:results (transient [])})))))
|
|
111
|
+
|
|
112
|
+
(let [pattern (PullSpec. true {})] ;; For performance purposes?
|
|
113
|
+
(defn- expand-frame
|
|
114
|
+
[parent eid attr-key multi? eids]
|
|
115
|
+
(let [rec (push-recursion (:recursion parent) attr-key eid)]
|
|
116
|
+
(-> pattern
|
|
117
|
+
(subpattern-frame eids multi? attr-key)
|
|
118
|
+
(assoc :recursion rec)))))
|
|
119
|
+
|
|
120
|
+
(defn db-ident-and-id [db x]
|
|
121
|
+
(let [{:keys [ident ref]} (dbu/attr-info db x)]
|
|
122
|
+
(if (dbu/ident-name? ident)
|
|
123
|
+
{:db/id ref :db/ident ident}
|
|
124
|
+
{:db/id ref})))
|
|
125
|
+
|
|
126
|
+
(defn pull-attr-datoms
|
|
127
|
+
"Processes datoms found to requested pattern for given attribute, i.e.
|
|
128
|
+
- limits the result set to specified or default limit,
|
|
129
|
+
- renames attribute key if requested,
|
|
130
|
+
- adds default value on missing attributes if requested.
|
|
131
|
+
Adds frame if
|
|
132
|
+
- subpattern requested on attribute,
|
|
133
|
+
- recursion requested,
|
|
134
|
+
- attribute is reference.
|
|
135
|
+
Returns frame set."
|
|
136
|
+
[db attr-key attr eid forward? datoms opts [parent & frames]]
|
|
137
|
+
(let [limit (get opts :limit +default-limit+)
|
|
138
|
+
attr-key (or (:as opts) attr-key)
|
|
139
|
+
found (not-empty
|
|
140
|
+
(cond->> datoms
|
|
141
|
+
limit (into [] (take limit))))]
|
|
142
|
+
(if found
|
|
143
|
+
(let [ref? (dbu/ref? db attr)
|
|
144
|
+
system-attrib-ref? (dbu/system-attrib-ref? db attr)
|
|
145
|
+
component? (and ref? (dbu/component? db attr))
|
|
146
|
+
multi? (if forward? (dbu/multival? db attr)
|
|
147
|
+
(not component?))
|
|
148
|
+
datom-val (if forward? (fn [d] (.-v ^Datom d))
|
|
149
|
+
(fn [d] (.-e ^Datom d)))]
|
|
150
|
+
|
|
151
|
+
(cond
|
|
152
|
+
(contains? opts :subpattern)
|
|
153
|
+
(->> (subpattern-frame (:subpattern opts)
|
|
154
|
+
(mapv datom-val found)
|
|
155
|
+
multi? attr-key)
|
|
156
|
+
(conj frames parent))
|
|
157
|
+
|
|
158
|
+
(contains? opts :recursion)
|
|
159
|
+
(recurse-attr db attr-key multi?
|
|
160
|
+
(mapv datom-val found)
|
|
161
|
+
eid parent frames)
|
|
162
|
+
|
|
163
|
+
(and component? forward?)
|
|
164
|
+
(->> found
|
|
165
|
+
(mapv datom-val)
|
|
166
|
+
(expand-frame parent eid attr-key multi?)
|
|
167
|
+
(conj frames parent))
|
|
168
|
+
|
|
169
|
+
:else
|
|
170
|
+
(let [as-value (if (or ref? system-attrib-ref?)
|
|
171
|
+
#(db-ident-and-id db (datom-val %))
|
|
172
|
+
datom-val)
|
|
173
|
+
single? (not multi?)]
|
|
174
|
+
(->> (cond-> (into [] (map as-value) found)
|
|
175
|
+
single? first)
|
|
176
|
+
(update parent :kvps assoc! attr-key)
|
|
177
|
+
(conj frames)))))
|
|
178
|
+
(->> (cond-> parent
|
|
179
|
+
(contains? opts :default)
|
|
180
|
+
(update :kvps assoc! attr-key (:default opts)))
|
|
181
|
+
(conj frames)))))
|
|
182
|
+
|
|
183
|
+
(defn pull-attr
|
|
184
|
+
"Retrieve datoms for given entity id and specification from database"
|
|
185
|
+
[db spec eid frames]
|
|
186
|
+
(let [[attr-key opts] spec]
|
|
187
|
+
(if (= :db/id attr-key)
|
|
188
|
+
(if (not-empty (dbi/datoms db :eavt [eid]))
|
|
189
|
+
(conj (rest frames)
|
|
190
|
+
(update (first frames) :kvps assoc! :db/id eid))
|
|
191
|
+
frames)
|
|
192
|
+
(let [attr (:attr opts)
|
|
193
|
+
forward? (= attr-key attr)
|
|
194
|
+
a (if (and (:attribute-refs? (dbi/-config db))
|
|
195
|
+
(not (number? attr)))
|
|
196
|
+
(dbi/-ref-for db attr)
|
|
197
|
+
attr)
|
|
198
|
+
results (if (nil? a)
|
|
199
|
+
[]
|
|
200
|
+
(if forward?
|
|
201
|
+
(dbi/datoms db :eavt [eid a])
|
|
202
|
+
(dbi/datoms db :avet [a eid])))]
|
|
203
|
+
(pull-attr-datoms db attr-key attr eid forward?
|
|
204
|
+
results opts frames)))))
|
|
205
|
+
|
|
206
|
+
(def ^:private filter-reverse-attrs
|
|
207
|
+
(filter (fn [[k v]] (not= k (:attr v)))))
|
|
208
|
+
|
|
209
|
+
(defn expand-reverse-subpattern-frame
|
|
210
|
+
[parent eid rattrs]
|
|
211
|
+
(-> (:pattern parent)
|
|
212
|
+
(assoc :attrs rattrs :wildcard? false)
|
|
213
|
+
(subpattern-frame [eid] false ::expand-rev)))
|
|
214
|
+
|
|
215
|
+
(defn expand-result
|
|
216
|
+
"Add intermediate result to frame next in line. Return frame set."
|
|
217
|
+
[frames kvps]
|
|
218
|
+
(->> kvps
|
|
219
|
+
(persistent!)
|
|
220
|
+
(update (first frames) :kvps into!)
|
|
221
|
+
(conj (rest frames))))
|
|
222
|
+
|
|
223
|
+
(defn pull-expand-reverse-frame
|
|
224
|
+
"Adds expand results of current frame to next frame in frame set."
|
|
225
|
+
[db [frame & frames]]
|
|
226
|
+
(->> (or (single-frame-result ::expand-rev frame) {})
|
|
227
|
+
(into! (:expand-kvps frame))
|
|
228
|
+
(expand-result frames)))
|
|
229
|
+
|
|
230
|
+
(defn pull-expand-frame
|
|
231
|
+
"Processes datoms for one attribute or changes frame state to process reverse attributes
|
|
232
|
+
and spawns new frame for subpattern."
|
|
233
|
+
[db [frame & frames]]
|
|
234
|
+
(if-let [datoms-by-attr (seq (:datoms frame))]
|
|
235
|
+
(let [[attr datoms] (first datoms-by-attr)
|
|
236
|
+
opts (-> frame
|
|
237
|
+
(get-in [:pattern :attrs])
|
|
238
|
+
(get attr {}))]
|
|
239
|
+
(pull-attr-datoms db attr attr (:eid frame) true datoms opts
|
|
240
|
+
(conj frames (update frame :datoms rest))))
|
|
241
|
+
(if-let [rattrs (->> (get-in frame [:pattern :attrs])
|
|
242
|
+
(into {} filter-reverse-attrs)
|
|
243
|
+
not-empty)]
|
|
244
|
+
(let [frame (assoc frame
|
|
245
|
+
:state :expand-rev
|
|
246
|
+
:expand-kvps (:kvps frame)
|
|
247
|
+
:kvps (transient {}))]
|
|
248
|
+
(->> rattrs
|
|
249
|
+
(expand-reverse-subpattern-frame frame (:eid frame))
|
|
250
|
+
(conj frames frame)))
|
|
251
|
+
(expand-result frames (:kvps frame)))))
|
|
252
|
+
|
|
253
|
+
(defn pull-wildcard-expand
|
|
254
|
+
[db frame frames eid pattern]
|
|
255
|
+
(let [datoms (group-by (fn [d] (if (:attribute-refs? (dbi/-config db))
|
|
256
|
+
(dbi/-ident-for db (.-a ^Datom d))
|
|
257
|
+
(.-a ^Datom d)))
|
|
258
|
+
(dbi/datoms db :eavt [eid]))
|
|
259
|
+
{:keys [attr recursion]} frame
|
|
260
|
+
rec (cond-> recursion
|
|
261
|
+
(some? attr) (push-recursion attr eid))]
|
|
262
|
+
(->> {:state :expand :kvps (transient {:db/id eid})
|
|
263
|
+
:eid eid :pattern pattern :datoms (seq datoms)
|
|
264
|
+
:recursion rec}
|
|
265
|
+
(conj frames frame)
|
|
266
|
+
(pull-expand-frame db))))
|
|
267
|
+
|
|
268
|
+
(defn pull-wildcard
|
|
269
|
+
[db frame frames]
|
|
270
|
+
(let [{:keys [eid pattern]} frame]
|
|
271
|
+
(or (pull-seen-eid frame frames eid)
|
|
272
|
+
(pull-wildcard-expand db frame frames eid pattern))))
|
|
273
|
+
|
|
274
|
+
(defn pull-pattern-frame
|
|
275
|
+
[db [frame & frames]]
|
|
276
|
+
(if-let [eids (seq (:eids frame))]
|
|
277
|
+
(if (:wildcard? frame)
|
|
278
|
+
(pull-wildcard db
|
|
279
|
+
(assoc frame
|
|
280
|
+
:specs []
|
|
281
|
+
:eid (first eids)
|
|
282
|
+
:wildcard? false)
|
|
283
|
+
frames)
|
|
284
|
+
(if-let [specs (seq (:specs frame))]
|
|
285
|
+
(let [spec (first specs)
|
|
286
|
+
new-frames (conj frames (assoc frame :specs (rest specs)))]
|
|
287
|
+
(pull-attr db spec (first eids) new-frames))
|
|
288
|
+
(->> frame :kvps persistent! not-empty
|
|
289
|
+
(reset-frame frame (rest eids))
|
|
290
|
+
(conj frames)
|
|
291
|
+
(recur db))))
|
|
292
|
+
(conj frames (assoc frame :state :done))))
|
|
293
|
+
|
|
294
|
+
(defn pull-pattern
|
|
295
|
+
[db frames]
|
|
296
|
+
(case (:state (first frames))
|
|
297
|
+
:expand (recur db (pull-expand-frame db frames))
|
|
298
|
+
:expand-rev (recur db (pull-expand-reverse-frame db frames))
|
|
299
|
+
:pattern (recur db (pull-pattern-frame db frames))
|
|
300
|
+
:recursion (recur db (pull-recursion-frame db frames))
|
|
301
|
+
:done (let [[f & remaining] frames
|
|
302
|
+
result (cond-> (persistent! (:results f))
|
|
303
|
+
(not (:multi? f)) first)]
|
|
304
|
+
(if (seq remaining)
|
|
305
|
+
(->> (cond-> (first remaining)
|
|
306
|
+
result (update :kvps assoc! (:attr f) result))
|
|
307
|
+
(conj (rest remaining))
|
|
308
|
+
(recur db))
|
|
309
|
+
result))))
|
|
310
|
+
|
|
311
|
+
(defn pull-spec
|
|
312
|
+
[db pattern eids multi?]
|
|
313
|
+
(let [eids (into [] (map #(dbu/entid-strict db %)) eids)]
|
|
314
|
+
(pull-pattern db (list (initial-frame pattern eids multi?)))))
|
|
315
|
+
|
|
316
|
+
(defn pull
|
|
317
|
+
([db {:keys [selector eid]}]
|
|
318
|
+
(pull db selector eid))
|
|
319
|
+
([db selector eid]
|
|
320
|
+
{:pre [(dbu/db? db)]}
|
|
321
|
+
(pull-spec db (dpp/parse-pull selector) [eid] false)))
|
|
322
|
+
|
|
323
|
+
(defn pull-many [db selector eids]
|
|
324
|
+
{:pre [(dbu/db? db)]}
|
|
325
|
+
(pull-spec db (dpp/parse-pull selector) eids true))
|