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,474 @@
|
|
|
1
|
+
(ns datahike.test.pull-api-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
5
|
+
[datahike.api :as d]
|
|
6
|
+
[datahike.db :as db]
|
|
7
|
+
[datahike.datom :as dd]
|
|
8
|
+
[datahike.pull-api :as p]
|
|
9
|
+
[datahike.constants :refer [tx0]]
|
|
10
|
+
[datahike.test.core-test]
|
|
11
|
+
[datalog.parser.pull :as dpp]))
|
|
12
|
+
|
|
13
|
+
(def test-schema
|
|
14
|
+
{:aka {:db/cardinality :db.cardinality/many}
|
|
15
|
+
:child {:db/cardinality :db.cardinality/many
|
|
16
|
+
:db/valueType :db.type/ref}
|
|
17
|
+
:friend {:db/cardinality :db.cardinality/many
|
|
18
|
+
:db/valueType :db.type/ref}
|
|
19
|
+
:enemy {:db/cardinality :db.cardinality/many
|
|
20
|
+
:db/valueType :db.type/ref}
|
|
21
|
+
:father {:db/valueType :db.type/ref}
|
|
22
|
+
:part {:db/valueType :db.type/ref
|
|
23
|
+
:db/isComponent true
|
|
24
|
+
:db/cardinality :db.cardinality/many}
|
|
25
|
+
:spec {:db/valueType :db.type/ref
|
|
26
|
+
:db/isComponent true
|
|
27
|
+
:db/cardinality :db.cardinality/one}})
|
|
28
|
+
|
|
29
|
+
(def test-datoms
|
|
30
|
+
(->>
|
|
31
|
+
[[1 :name "Petr"]
|
|
32
|
+
[1 :aka "Devil"]
|
|
33
|
+
[1 :aka "Tupen"]
|
|
34
|
+
[2 :name "David"]
|
|
35
|
+
[3 :name "Thomas"]
|
|
36
|
+
[4 :name "Lucy"]
|
|
37
|
+
[5 :name "Elizabeth"]
|
|
38
|
+
[6 :name "Matthew"]
|
|
39
|
+
[7 :name "Eunan"]
|
|
40
|
+
[8 :name "Kerri"]
|
|
41
|
+
[9 :name "Rebecca"]
|
|
42
|
+
[1 :child 2]
|
|
43
|
+
[1 :child 3]
|
|
44
|
+
[2 :father 1]
|
|
45
|
+
[3 :father 1]
|
|
46
|
+
[6 :father 3]
|
|
47
|
+
[10 :name "Part A"]
|
|
48
|
+
[11 :name "Part A.A"]
|
|
49
|
+
[10 :part 11]
|
|
50
|
+
[12 :name "Part A.A.A"]
|
|
51
|
+
[11 :part 12]
|
|
52
|
+
[13 :name "Part A.A.A.A"]
|
|
53
|
+
[12 :part 13]
|
|
54
|
+
[14 :name "Part A.A.A.B"]
|
|
55
|
+
[12 :part 14]
|
|
56
|
+
[15 :name "Part A.B"]
|
|
57
|
+
[10 :part 15]
|
|
58
|
+
[16 :name "Part A.B.A"]
|
|
59
|
+
[15 :part 16]
|
|
60
|
+
[17 :name "Part A.B.A.A"]
|
|
61
|
+
[16 :part 17]
|
|
62
|
+
[18 :name "Part A.B.A.B"]
|
|
63
|
+
[16 :part 18]]
|
|
64
|
+
(map (fn [[e a v]] (dd/datom e a v tx0)))))
|
|
65
|
+
|
|
66
|
+
(def test-db (db/init-db test-datoms test-schema))
|
|
67
|
+
|
|
68
|
+
(deftest test-pull-attr-spec
|
|
69
|
+
(is (= {:name "Petr" :aka ["Devil" "Tupen"]}
|
|
70
|
+
(d/pull test-db '[:name :aka] 1)))
|
|
71
|
+
|
|
72
|
+
(is (= {:name "Matthew" :father {:db/id 3} :db/id 6}
|
|
73
|
+
(d/pull test-db '[:name :father :db/id] 6)))
|
|
74
|
+
|
|
75
|
+
(is (= [{:name "Petr"} {:name "Elizabeth"}
|
|
76
|
+
{:name "Eunan"} {:name "Rebecca"}]
|
|
77
|
+
(d/pull-many test-db '[:name] [1 5 7 9]))))
|
|
78
|
+
|
|
79
|
+
(deftest test-pull-reverse-attr-spec
|
|
80
|
+
(is (= {:name "David" :_child [{:db/id 1}]}
|
|
81
|
+
(d/pull test-db '[:name :_child] 2)))
|
|
82
|
+
|
|
83
|
+
(is (= {:name "David" :_child [{:name "Petr"}]}
|
|
84
|
+
(d/pull test-db '[:name {:_child [:name]}] 2)))
|
|
85
|
+
|
|
86
|
+
(testing "Reverse non-component references yield collections"
|
|
87
|
+
(is (= {:name "Thomas" :_father [{:db/id 6}]}
|
|
88
|
+
(d/pull test-db '[:name :_father] 3)))
|
|
89
|
+
|
|
90
|
+
(is (= {:name "Petr" :_father [{:db/id 2} {:db/id 3}]}
|
|
91
|
+
(d/pull test-db '[:name :_father] 1)))
|
|
92
|
+
|
|
93
|
+
(is (= {:name "Thomas" :_father [{:name "Matthew"}]}
|
|
94
|
+
(d/pull test-db '[:name {:_father [:name]}] 3)))
|
|
95
|
+
|
|
96
|
+
(is (= {:name "Petr" :_father [{:name "David"} {:name "Thomas"}]}
|
|
97
|
+
(d/pull test-db '[:name {:_father [:name]}] 1)))))
|
|
98
|
+
|
|
99
|
+
(deftest test-pull-component-attr
|
|
100
|
+
(let [parts {:name "Part A",
|
|
101
|
+
:part
|
|
102
|
+
[{:db/id 11
|
|
103
|
+
:name "Part A.A",
|
|
104
|
+
:part
|
|
105
|
+
[{:db/id 12
|
|
106
|
+
:name "Part A.A.A",
|
|
107
|
+
:part
|
|
108
|
+
[{:db/id 13 :name "Part A.A.A.A"}
|
|
109
|
+
{:db/id 14 :name "Part A.A.A.B"}]}]}
|
|
110
|
+
{:db/id 15
|
|
111
|
+
:name "Part A.B",
|
|
112
|
+
:part
|
|
113
|
+
[{:db/id 16
|
|
114
|
+
:name "Part A.B.A",
|
|
115
|
+
:part
|
|
116
|
+
[{:db/id 17 :name "Part A.B.A.A"}
|
|
117
|
+
{:db/id 18 :name "Part A.B.A.B"}]}]}]}
|
|
118
|
+
rpart (update-in parts [:part 0 :part 0 :part]
|
|
119
|
+
(partial into [{:db/id 10}]))
|
|
120
|
+
recdb (db/init-db
|
|
121
|
+
(concat test-datoms [(dd/datom 12 :part 10)])
|
|
122
|
+
test-schema)
|
|
123
|
+
|
|
124
|
+
mutdb (db/init-db
|
|
125
|
+
(concat test-datoms [(dd/datom 12 :part 10)
|
|
126
|
+
(dd/datom 12 :spec 10)
|
|
127
|
+
(dd/datom 10 :spec 13)
|
|
128
|
+
(dd/datom 13 :spec 12)])
|
|
129
|
+
test-schema)]
|
|
130
|
+
|
|
131
|
+
(testing "Component entities are expanded recursively"
|
|
132
|
+
(is (= parts (d/pull test-db '[:name :part] 10))))
|
|
133
|
+
|
|
134
|
+
(testing "Reverse component references yield a single result"
|
|
135
|
+
(is (= {:name "Part A.A" :_part {:db/id 10}}
|
|
136
|
+
(d/pull test-db [:name :_part] 11)))
|
|
137
|
+
|
|
138
|
+
(is (= {:name "Part A.A" :_part {:name "Part A"}}
|
|
139
|
+
(d/pull test-db [:name {:_part [:name]}] 11))))
|
|
140
|
+
|
|
141
|
+
(testing "Like explicit recursion, expansion will not allow loops"
|
|
142
|
+
(is (= rpart (d/pull recdb '[:name :part] 10))))))
|
|
143
|
+
|
|
144
|
+
(deftest test-pull-wildcard-pattern
|
|
145
|
+
(is (= {:db/id 1 :name "Petr" :aka ["Devil" "Tupen"]
|
|
146
|
+
:child [{:db/id 2} {:db/id 3}]}
|
|
147
|
+
(d/pull test-db '[*] 1)))
|
|
148
|
+
|
|
149
|
+
(is (= {:db/id 2 :name "David" :_child [{:db/id 1}] :father {:db/id 1}}
|
|
150
|
+
(d/pull test-db '[* :_child] 2))))
|
|
151
|
+
|
|
152
|
+
(deftest test-pull-limit
|
|
153
|
+
(let [db (db/init-db
|
|
154
|
+
(concat
|
|
155
|
+
test-datoms
|
|
156
|
+
[(dd/datom 4 :friend 5)
|
|
157
|
+
(dd/datom 4 :friend 6)
|
|
158
|
+
(dd/datom 4 :friend 7)
|
|
159
|
+
(dd/datom 4 :friend 8)]
|
|
160
|
+
(for [idx (range 2000)]
|
|
161
|
+
(dd/datom 8 :aka (str "aka-" idx))))
|
|
162
|
+
test-schema)]
|
|
163
|
+
|
|
164
|
+
(testing "Without an explicit limit, the default is 1000"
|
|
165
|
+
(is (= 1000 (->> (d/pull db '[:aka] 8) :aka count))))
|
|
166
|
+
|
|
167
|
+
(testing "Explicit limit can reduce the default"
|
|
168
|
+
(is (= 500 (->> (d/pull db '[(limit :aka 500)] 8) :aka count)))
|
|
169
|
+
(is (= 500 (->> (d/pull db '[[:aka :limit 500]] 8) :aka count))))
|
|
170
|
+
|
|
171
|
+
(testing "Explicit limit can increase the default"
|
|
172
|
+
(is (= 1500 (->> (d/pull db '[(limit :aka 1500)] 8) :aka count))))
|
|
173
|
+
|
|
174
|
+
(testing "A nil limit produces unlimited results"
|
|
175
|
+
(is (= 2000 (->> (d/pull db '[(limit :aka nil)] 8) :aka count))))
|
|
176
|
+
|
|
177
|
+
(testing "Limits can be used as map specification keys"
|
|
178
|
+
(is (= {:name "Lucy"
|
|
179
|
+
:friend [{:name "Elizabeth"} {:name "Matthew"}]}
|
|
180
|
+
(d/pull db '[:name {(limit :friend 2) [:name]}] 4))))))
|
|
181
|
+
|
|
182
|
+
(deftest test-pull-default
|
|
183
|
+
(testing "Empty results return nil"
|
|
184
|
+
(is (nil? (d/pull test-db '[:foo] 1))))
|
|
185
|
+
|
|
186
|
+
(testing "A default can be used to replace nil results"
|
|
187
|
+
(is (= {:foo "bar"}
|
|
188
|
+
(d/pull test-db '[(default :foo "bar")] 1)))
|
|
189
|
+
(is (= {:foo "bar"}
|
|
190
|
+
(d/pull test-db '[[:foo :default "bar"]] 1)))))
|
|
191
|
+
|
|
192
|
+
(deftest test-pull-as
|
|
193
|
+
(is (= {"Name" "Petr", :alias ["Devil" "Tupen"]}
|
|
194
|
+
(d/pull test-db '[[:name :as "Name"] [:aka :as :alias]] 1))))
|
|
195
|
+
|
|
196
|
+
(deftest test-pull-attr-with-opts
|
|
197
|
+
(is (= {"Name" "Nothing"}
|
|
198
|
+
(d/pull test-db '[[:x :as "Name" :default "Nothing"]] 1))))
|
|
199
|
+
|
|
200
|
+
(deftest test-pull-map
|
|
201
|
+
(testing "Single attrs yield a map"
|
|
202
|
+
(is (= {:name "Matthew" :father {:name "Thomas"}}
|
|
203
|
+
(d/pull test-db '[:name {:father [:name]}] 6))))
|
|
204
|
+
|
|
205
|
+
(testing "Multi attrs yield a collection of maps"
|
|
206
|
+
(is (= {:name "Petr" :child [{:name "David"}
|
|
207
|
+
{:name "Thomas"}]}
|
|
208
|
+
(d/pull test-db '[:name {:child [:name]}] 1))))
|
|
209
|
+
|
|
210
|
+
(testing "Missing attrs are dropped"
|
|
211
|
+
(is (= {:name "Petr"}
|
|
212
|
+
(d/pull test-db '[:name {:father [:name]}] 1))))
|
|
213
|
+
|
|
214
|
+
(testing "Non matching results are removed from collections"
|
|
215
|
+
(is (= {:name "Petr" :child []}
|
|
216
|
+
(d/pull test-db '[:name {:child [:foo]}] 1))))
|
|
217
|
+
|
|
218
|
+
(testing "Map specs can override component expansion"
|
|
219
|
+
(let [parts {:name "Part A" :part [{:name "Part A.A"} {:name "Part A.B"}]}]
|
|
220
|
+
(is (= parts
|
|
221
|
+
(d/pull test-db '[:name {:part [:name]}] 10)))
|
|
222
|
+
|
|
223
|
+
(is (= parts
|
|
224
|
+
(d/pull test-db '[:name {:part 1}] 10))))))
|
|
225
|
+
|
|
226
|
+
(deftest test-pull-recursion
|
|
227
|
+
(let [db (-> test-db
|
|
228
|
+
(d/db-with [[:db/add 4 :friend 5]
|
|
229
|
+
[:db/add 5 :friend 6]
|
|
230
|
+
[:db/add 6 :friend 7]
|
|
231
|
+
[:db/add 7 :friend 8]
|
|
232
|
+
[:db/add 4 :enemy 6]
|
|
233
|
+
[:db/add 5 :enemy 7]
|
|
234
|
+
[:db/add 6 :enemy 8]
|
|
235
|
+
[:db/add 7 :enemy 4]]))
|
|
236
|
+
friends {:db/id 4
|
|
237
|
+
:name "Lucy"
|
|
238
|
+
:friend
|
|
239
|
+
[{:db/id 5
|
|
240
|
+
:name "Elizabeth"
|
|
241
|
+
:friend
|
|
242
|
+
[{:db/id 6
|
|
243
|
+
:name "Matthew"
|
|
244
|
+
:friend
|
|
245
|
+
[{:db/id 7
|
|
246
|
+
:name "Eunan"
|
|
247
|
+
:friend
|
|
248
|
+
[{:db/id 8
|
|
249
|
+
:name "Kerri"}]}]}]}]}
|
|
250
|
+
enemies {:db/id 4 :name "Lucy"
|
|
251
|
+
:friend
|
|
252
|
+
[{:db/id 5 :name "Elizabeth"
|
|
253
|
+
:friend
|
|
254
|
+
[{:db/id 6 :name "Matthew"
|
|
255
|
+
:enemy [{:db/id 8 :name "Kerri"}]}]
|
|
256
|
+
:enemy
|
|
257
|
+
[{:db/id 7 :name "Eunan"
|
|
258
|
+
:friend
|
|
259
|
+
[{:db/id 8 :name "Kerri"}]
|
|
260
|
+
:enemy
|
|
261
|
+
[{:db/id 4 :name "Lucy"
|
|
262
|
+
:friend [{:db/id 5}]}]}]}]
|
|
263
|
+
:enemy
|
|
264
|
+
[{:db/id 6 :name "Matthew"
|
|
265
|
+
:friend
|
|
266
|
+
[{:db/id 7 :name "Eunan"
|
|
267
|
+
:friend
|
|
268
|
+
[{:db/id 8 :name "Kerri"}]
|
|
269
|
+
:enemy [{:db/id 4 :name "Lucy"
|
|
270
|
+
:friend [{:db/id 5 :name "Elizabeth"}]}]}]
|
|
271
|
+
:enemy
|
|
272
|
+
[{:db/id 8 :name "Kerri"}]}]}]
|
|
273
|
+
|
|
274
|
+
(testing "Infinite recursion"
|
|
275
|
+
(is (= friends (d/pull db '[:db/id :name {:friend ...}] 4))))
|
|
276
|
+
|
|
277
|
+
(testing "Multiple recursion specs in one pattern"
|
|
278
|
+
(is (= enemies (d/pull db '[:db/id :name {:friend 2 :enemy 2}] 4))))
|
|
279
|
+
|
|
280
|
+
(let [db (d/db-with db [[:db/add 8 :friend 4]])]
|
|
281
|
+
(testing "Cycles are handled by returning only the :db/id of entities which have been seen before"
|
|
282
|
+
(is (= (update-in friends (take 8 (cycle [:friend 0]))
|
|
283
|
+
assoc :friend [{:db/id 4 :name "Lucy" :friend [{:db/id 5}]}])
|
|
284
|
+
(d/pull db '[:db/id :name {:friend ...}] 4)))))))
|
|
285
|
+
|
|
286
|
+
(deftest test-dual-recursion
|
|
287
|
+
(let [empty (db/empty-db {:part {:db/valueType :db.type/ref}
|
|
288
|
+
:spec {:db/valueType :db.type/ref}})
|
|
289
|
+
db (d/db-with empty [[:db/add 1 :part 2]
|
|
290
|
+
[:db/add 2 :part 3]
|
|
291
|
+
[:db/add 3 :part 1]
|
|
292
|
+
[:db/add 1 :spec 2]
|
|
293
|
+
[:db/add 2 :spec 1]])]
|
|
294
|
+
(is (= (d/pull db '[:db/id {:part ...} {:spec ...}] 1)
|
|
295
|
+
{:db/id 1,
|
|
296
|
+
:spec {:db/id 2
|
|
297
|
+
:spec {:db/id 1,
|
|
298
|
+
:spec {:db/id 2}, :part {:db/id 2}}
|
|
299
|
+
:part {:db/id 3,
|
|
300
|
+
:part {:db/id 1,
|
|
301
|
+
:spec {:db/id 2},
|
|
302
|
+
:part {:db/id 2}}}}
|
|
303
|
+
:part {:db/id 2
|
|
304
|
+
:spec {:db/id 1, :spec {:db/id 2}, :part {:db/id 2}}
|
|
305
|
+
:part {:db/id 3,
|
|
306
|
+
:part {:db/id 1,
|
|
307
|
+
:spec {:db/id 2},
|
|
308
|
+
:part {:db/id 2}}}}}))))
|
|
309
|
+
|
|
310
|
+
(deftest test-deep-recursion
|
|
311
|
+
(let [start 100
|
|
312
|
+
depth 1500
|
|
313
|
+
txd (mapcat
|
|
314
|
+
(fn [idx]
|
|
315
|
+
[(dd/datom idx :name (str "Person-" idx))
|
|
316
|
+
(dd/datom (dec idx) :friend idx)])
|
|
317
|
+
(range (inc start) depth))
|
|
318
|
+
db (db/init-db (concat
|
|
319
|
+
test-datoms
|
|
320
|
+
[(dd/datom start :name (str "Person-" start))]
|
|
321
|
+
txd)
|
|
322
|
+
test-schema)
|
|
323
|
+
pulled (d/pull db '[:name {:friend ...}] start)
|
|
324
|
+
path (->> [:friend 0]
|
|
325
|
+
(repeat (dec (- depth start)))
|
|
326
|
+
(into [] cat))]
|
|
327
|
+
(is (= (str "Person-" (dec depth))
|
|
328
|
+
(:name (get-in pulled path))))))
|
|
329
|
+
|
|
330
|
+
;; Helper functions
|
|
331
|
+
|
|
332
|
+
(def empty-frame
|
|
333
|
+
"Needs at least eids, specs, pattern to be assigned"
|
|
334
|
+
{:multi? false
|
|
335
|
+
:state :pattern
|
|
336
|
+
:specs '()
|
|
337
|
+
:recursion {:depth {}, :seen #{}}
|
|
338
|
+
:wildcard? false})
|
|
339
|
+
|
|
340
|
+
(deftest test-pull-spec
|
|
341
|
+
(let [spec (dpp/->PullSpec false {:name {:attr :name}})]
|
|
342
|
+
(is (= (p/pull-spec test-db spec [1] false)
|
|
343
|
+
{:name "Petr"}))
|
|
344
|
+
(is (= (p/pull-spec test-db spec [1] true)
|
|
345
|
+
[{:name "Petr"}]))))
|
|
346
|
+
|
|
347
|
+
(deftest test-pull-pattern
|
|
348
|
+
(let [frame (merge empty-frame
|
|
349
|
+
{:eids [1]
|
|
350
|
+
:specs '([:name {:attr :name}])
|
|
351
|
+
:pattern (dpp/->PullSpec false {})
|
|
352
|
+
:results (transient [])
|
|
353
|
+
:kvps (transient {})})]
|
|
354
|
+
(is (= (p/pull-pattern test-db [frame])
|
|
355
|
+
{:name "Petr"}))))
|
|
356
|
+
|
|
357
|
+
(dpp/->PullSpec false {:name {:attr :name}})
|
|
358
|
+
|
|
359
|
+
(deftest test-pull-pattern-frame
|
|
360
|
+
(let [frame (merge empty-frame
|
|
361
|
+
{:eids [1]
|
|
362
|
+
:specs '([:name {:attr :name}])
|
|
363
|
+
:pattern (dpp/->PullSpec false {})
|
|
364
|
+
:kvps (transient {})})
|
|
365
|
+
ppf (p/pull-pattern-frame test-db [frame])]
|
|
366
|
+
(is (= (count ppf) 1))
|
|
367
|
+
(is (= (persistent! (:kvps (first ppf)))
|
|
368
|
+
{:name "Petr"}))))
|
|
369
|
+
|
|
370
|
+
(deftest test-pull-attr
|
|
371
|
+
(let [frame (merge empty-frame
|
|
372
|
+
{:eids [1]
|
|
373
|
+
:pattern (dpp/->PullSpec false {})
|
|
374
|
+
:kvps (transient {})})
|
|
375
|
+
res (p/pull-attr test-db [:name {:attr :name}] 1 [frame])]
|
|
376
|
+
(is (= (persistent! (:kvps (first res)))
|
|
377
|
+
{:name "Petr"}))))
|
|
378
|
+
|
|
379
|
+
(deftest test-pull-attr-datoms
|
|
380
|
+
(let [datom (dd/datom 1 :name "Petr" 536870912 true)
|
|
381
|
+
opts {:attr :name}
|
|
382
|
+
frame (merge empty-frame
|
|
383
|
+
{:eids [1]
|
|
384
|
+
:pattern (dpp/->PullSpec false {})
|
|
385
|
+
:kvps (transient {})})
|
|
386
|
+
res (p/pull-attr-datoms test-db :name {:attr :name} 1 true [datom] opts [frame])]
|
|
387
|
+
(is (= (persistent! (:kvps (first res)))
|
|
388
|
+
{:name "Petr"}))))
|
|
389
|
+
|
|
390
|
+
(deftest test-pull-wildcard
|
|
391
|
+
(let [frame (merge empty-frame
|
|
392
|
+
{:eids [1]
|
|
393
|
+
:eid 1
|
|
394
|
+
:wildcard? false
|
|
395
|
+
:pattern (dpp/->PullSpec false {})
|
|
396
|
+
:results (transient [])
|
|
397
|
+
:kvps (transient {})})
|
|
398
|
+
res (p/pull-wildcard test-db frame nil)]
|
|
399
|
+
(is (= (persistent! (:kvps (first res)))
|
|
400
|
+
{:db/id 1, :aka ["Devil" "Tupen"]}))))
|
|
401
|
+
|
|
402
|
+
(deftest test-pull-wildcard-expand
|
|
403
|
+
(let [pattern (dpp/->PullSpec false {})
|
|
404
|
+
frame {:multi? false,
|
|
405
|
+
:eids [1]
|
|
406
|
+
:state :pattern
|
|
407
|
+
:recursion {:depth {}, :seen #{}},
|
|
408
|
+
:specs '(),
|
|
409
|
+
:wildcard? false,
|
|
410
|
+
:results (transient [])
|
|
411
|
+
:kvps (transient {})
|
|
412
|
+
:pattern pattern}
|
|
413
|
+
res (p/pull-wildcard-expand test-db frame nil 1 pattern)]
|
|
414
|
+
(is (= (persistent! (:kvps (first res)))
|
|
415
|
+
{:db/id 1, :aka ["Devil" "Tupen"]}))))
|
|
416
|
+
|
|
417
|
+
(deftest test-pull-expand-frame
|
|
418
|
+
(let [parent {:state :pattern
|
|
419
|
+
:specs '()
|
|
420
|
+
:results (transient [])
|
|
421
|
+
:kvps (transient {})
|
|
422
|
+
:eids [1]
|
|
423
|
+
:pattern (dpp/->PullSpec false {})}
|
|
424
|
+
frame {:state :expand
|
|
425
|
+
:kvps (transient {})
|
|
426
|
+
:eid 1
|
|
427
|
+
:pattern (dpp/->PullSpec false {})
|
|
428
|
+
:datoms (list [:aka [(dd/datom 1 :aka "Devil" 536870912 true)
|
|
429
|
+
(dd/datom 1 :aka "Tupen" 536870912 true)]]
|
|
430
|
+
[:child [(dd/datom 1 :child 2 536870912 true)
|
|
431
|
+
(dd/datom 1 :child 3 536870912 true)]]
|
|
432
|
+
[:name [(dd/datom 1 :name "Petr" 536870912 true)]])
|
|
433
|
+
:recursion {:depth {}, :seen #{}}}
|
|
434
|
+
|
|
435
|
+
frames (seq [frame parent])
|
|
436
|
+
res (p/pull-expand-frame test-db frames)]
|
|
437
|
+
(is (= (persistent! (:kvps (first res)))
|
|
438
|
+
{:aka ["Devil" "Tupen"]}))
|
|
439
|
+
(is (= (:datoms (first res))
|
|
440
|
+
(list [:child [(dd/datom 1 :child 2 536870912 true)
|
|
441
|
+
(dd/datom 1 :child 3 536870912 true)]]
|
|
442
|
+
[:name [(dd/datom 1 :name "Petr" 536870912 true)]])))))
|
|
443
|
+
|
|
444
|
+
(deftest test-pull-recursion-frame
|
|
445
|
+
(let [db (d/db-with test-db [[:db/add 4 :friend 5]
|
|
446
|
+
[:db/add 5 :friend 6]])
|
|
447
|
+
parent {:state :pattern
|
|
448
|
+
:multi? false
|
|
449
|
+
:eids [5]
|
|
450
|
+
:recursion {:depth {:friend 1} :seen #{5}}
|
|
451
|
+
:specs '()
|
|
452
|
+
:wildcard? false
|
|
453
|
+
:kvps (transient {:db/id 5, :name "Elizabeth"})
|
|
454
|
+
:pattern (dpp/->PullSpec false {}),
|
|
455
|
+
:attr :datahike.pull-api/recursion
|
|
456
|
+
:results (transient [])}
|
|
457
|
+
frame {:state :recursion
|
|
458
|
+
:pattern (dpp/->PullSpec false {:db/id {:attr :db/id}
|
|
459
|
+
:name {:attr :name}
|
|
460
|
+
:friend {:attr :friend, :recursion nil}})
|
|
461
|
+
:attr :friend
|
|
462
|
+
:multi? true
|
|
463
|
+
:eids [6]
|
|
464
|
+
:recursion {:depth {:friend 1}, :seen #{5}}
|
|
465
|
+
:results (transient [])}
|
|
466
|
+
frames (seq [frame parent])
|
|
467
|
+
res (p/pull-recursion-frame db frames)]
|
|
468
|
+
(is (= (:recursion (first res))
|
|
469
|
+
{:depth {:friend 2} :seen #{5 6}}))
|
|
470
|
+
(is (= (:multi? (first res)) false))
|
|
471
|
+
(is (= (:specs (first res))
|
|
472
|
+
'([:db/id {:attr :db/id}]
|
|
473
|
+
[:name {:attr :name}]
|
|
474
|
+
[:friend {:attr :friend :recursion nil}])))))
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
(ns datahike.test.purge-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is are deftest testing]])
|
|
5
|
+
[datahike.api :as d]
|
|
6
|
+
[datahike.test.utils :as tu]))
|
|
7
|
+
|
|
8
|
+
#?(:cljs (def Throwable js/Error))
|
|
9
|
+
|
|
10
|
+
(def schema-tx [{:db/ident :name
|
|
11
|
+
:db/valueType :db.type/string
|
|
12
|
+
:db/unique :db.unique/identity
|
|
13
|
+
:db/index true
|
|
14
|
+
:db/cardinality :db.cardinality/one}
|
|
15
|
+
{:db/ident :age
|
|
16
|
+
:db/valueType :db.type/long
|
|
17
|
+
:db/cardinality :db.cardinality/one}
|
|
18
|
+
{:name "Alice"
|
|
19
|
+
:age 25}
|
|
20
|
+
{:name "Bob"
|
|
21
|
+
:age 35}])
|
|
22
|
+
|
|
23
|
+
(def cfg-template {:store {:backend :memory
|
|
24
|
+
:id #uuid "001b0000-0000-0000-0000-00000000001b"}
|
|
25
|
+
:keep-history? true
|
|
26
|
+
:schema-flexibility :write
|
|
27
|
+
:initial-tx schema-tx})
|
|
28
|
+
|
|
29
|
+
(defn find-age [db name]
|
|
30
|
+
(d/q '[:find ?a . :in $ ?n :where [?e :name ?n] [?e :age ?a]] db name))
|
|
31
|
+
|
|
32
|
+
(defn find-entity [db name]
|
|
33
|
+
(d/q '[:find (pull ?e [:name :age]) :in $ ?n :where [?e :name ?n]] db name))
|
|
34
|
+
|
|
35
|
+
(defn find-entities [db]
|
|
36
|
+
(into #{}
|
|
37
|
+
(d/q '[:find [(pull ?e [:name :age]) ...] :where [?e :name _]] db)))
|
|
38
|
+
|
|
39
|
+
(deftest test-purge
|
|
40
|
+
(let [conn (tu/setup-db (assoc-in cfg-template [:store :id] #uuid "09000000-0000-0000-0000-000000000001"))]
|
|
41
|
+
(testing "retract datom, data is removed from current db and found in history"
|
|
42
|
+
(let [name "Alice"]
|
|
43
|
+
(d/transact conn [[:db/retract [:name name] :age 25]])
|
|
44
|
+
(are [x y] (= x y)
|
|
45
|
+
true (nil? (find-age @conn name))
|
|
46
|
+
25 (find-age (d/history @conn) name))))
|
|
47
|
+
(testing "purge datom from current index and from history"
|
|
48
|
+
(let [name "Bob"]
|
|
49
|
+
(d/transact conn [[:db/purge [:name name] :age 35]])
|
|
50
|
+
(are [x y] (= x y)
|
|
51
|
+
true (nil? (find-age @conn name))
|
|
52
|
+
true (nil? (find-age (d/history @conn) name)))))
|
|
53
|
+
(testing "purge retracted datom"
|
|
54
|
+
(let [name "Alice"]
|
|
55
|
+
(d/transact conn [[:db/purge [:name name] :age 25]])
|
|
56
|
+
(are [x y] (= x y)
|
|
57
|
+
nil (find-age @conn name)
|
|
58
|
+
nil (find-age (d/history @conn) name))))
|
|
59
|
+
(d/release conn)))
|
|
60
|
+
|
|
61
|
+
(deftest test-purge-attribute
|
|
62
|
+
(let [conn (tu/setup-db (assoc-in cfg-template [:store :id] #uuid "09000000-0000-0000-0000-000000000002"))]
|
|
63
|
+
(testing "purge attribute from current index"
|
|
64
|
+
(let [name "Alice"]
|
|
65
|
+
(d/transact conn [[:db.purge/attribute [:name name] :age]])
|
|
66
|
+
(are [x y] (= x y)
|
|
67
|
+
true (nil? (find-age @conn name))
|
|
68
|
+
true (nil? (find-age (d/history @conn) name))
|
|
69
|
+
#{["Alice"] ["Bob"]} (d/q '[:find ?n :where [_ :name ?n]] @conn))))
|
|
70
|
+
(testing "retract attribute from current index and purge from history"
|
|
71
|
+
(let [name "Bob"]
|
|
72
|
+
(testing "retracting from current index"
|
|
73
|
+
(d/transact conn [[:db.fn/retractAttribute [:name name] :age]])
|
|
74
|
+
(are [x y] (= x y)
|
|
75
|
+
true (nil? (find-age @conn name))
|
|
76
|
+
35 (find-age (d/history @conn) name)))
|
|
77
|
+
(testing "purging from history"
|
|
78
|
+
(d/transact conn [[:db.purge/entity [:name name] :age]])
|
|
79
|
+
(are [x y] (= x y)
|
|
80
|
+
true (nil? (find-age @conn name))
|
|
81
|
+
true (nil? (find-age (d/history @conn) name))))))
|
|
82
|
+
(d/release conn)))
|
|
83
|
+
|
|
84
|
+
(deftest test-purge-entity
|
|
85
|
+
(let [conn (tu/setup-db (assoc-in cfg-template [:store :id] #uuid "09000000-0000-0000-0000-000000000003"))]
|
|
86
|
+
(testing "purge entity from current index"
|
|
87
|
+
(is (= #{{:name "Alice" :age 25} {:name "Bob" :age 35}} (find-entities @conn)))
|
|
88
|
+
(d/transact conn [[:db.purge/entity [:name "Alice"]]])
|
|
89
|
+
(is (= #{{:name "Bob" :age 35}} (find-entities @conn)))
|
|
90
|
+
(is (= #{{:name "Bob" :age 35}} (find-entities (d/history @conn)))))
|
|
91
|
+
(testing "retract entity from current index and purge from history"
|
|
92
|
+
(let [name "Bob"]
|
|
93
|
+
(testing "retracting from current index"
|
|
94
|
+
(d/transact conn [[:db/retractEntity [:name name]]])
|
|
95
|
+
(is (= #{} (find-entities @conn)))
|
|
96
|
+
(is (= #{{:name "Bob" :age 35}} (find-entities (d/history @conn)))))
|
|
97
|
+
(testing "purging from history"
|
|
98
|
+
(d/transact conn [[:db.purge/entity [:name name]]])
|
|
99
|
+
(is (= #{} (find-entities @conn)))
|
|
100
|
+
(is (= #{} (find-entities (d/history @conn)))))))
|
|
101
|
+
(testing "purge something that is not present in the database"
|
|
102
|
+
(is (thrown-with-msg? Throwable
|
|
103
|
+
#"Can't find entity with ID \[:name \"Alice\"\] to be purged"
|
|
104
|
+
(d/transact conn [[:db.purge/entity [:name "Alice"]]]))))
|
|
105
|
+
(d/release conn)))
|
|
106
|
+
|
|
107
|
+
(deftest test-purge-non-temporal-database
|
|
108
|
+
(let [conn (tu/setup-db (-> (assoc-in cfg-template [:store :id] #uuid "09000000-0000-0000-0000-000000000004")
|
|
109
|
+
(assoc :keep-history? false)))]
|
|
110
|
+
(testing "purge data in non temporal database"
|
|
111
|
+
(is (thrown-with-msg? Throwable #"Purge entity is only available in temporal databases\."
|
|
112
|
+
(d/transact conn [[:db.purge/entity [:name "Alice"]]]))))
|
|
113
|
+
(d/release conn)))
|
|
114
|
+
|
|
115
|
+
(defn find-ages [db name]
|
|
116
|
+
(d/q '[:find ?a ?op
|
|
117
|
+
:in $ ?n
|
|
118
|
+
:where
|
|
119
|
+
[?e :name ?n]
|
|
120
|
+
[?e :age ?a ?t ?op]]
|
|
121
|
+
db
|
|
122
|
+
name))
|
|
123
|
+
|
|
124
|
+
(deftest test-history-purge-before
|
|
125
|
+
(let [conn (tu/setup-db (assoc-in cfg-template [:store :id] #uuid "09000000-0000-0000-0000-000000000005"))
|
|
126
|
+
name "Alice"]
|
|
127
|
+
(testing "remove all historical data before date"
|
|
128
|
+
(is (= #{[25 true]}
|
|
129
|
+
(find-ages @conn name)))
|
|
130
|
+
(let [upsert-date (java.util.Date.)]
|
|
131
|
+
(d/transact conn [{:db/id [:name name] :age 30}])
|
|
132
|
+
(is (= #{[30 true]}
|
|
133
|
+
(find-ages @conn name)))
|
|
134
|
+
(is (= #{[25 true] [25 false] [30 true]}
|
|
135
|
+
(find-ages (d/history @conn) name)))
|
|
136
|
+
(d/transact conn [[:db.history.purge/before upsert-date]])
|
|
137
|
+
(is (= #{[30 true]}
|
|
138
|
+
(find-ages @conn name)))
|
|
139
|
+
(is (= #{[25 false] [30 true]}
|
|
140
|
+
(find-ages (d/history @conn) name)))
|
|
141
|
+
(d/transact conn [[:db.history.purge/before (java.util.Date.)]])
|
|
142
|
+
(is (= #{[30 true]}
|
|
143
|
+
(find-ages (d/history @conn) name)))))
|
|
144
|
+
(d/release conn)))
|