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,518 @@
|
|
|
1
|
+
(ns datahike.test.time-variance-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
|
+
#?(:cljs [datahike.cljs :refer [Throwable]])
|
|
7
|
+
[datahike.constants :as const]
|
|
8
|
+
[datahike.test.utils :as du]
|
|
9
|
+
[datahike.db.interface :as dbi]
|
|
10
|
+
[datahike.test.utils :refer [setup-db sleep]])
|
|
11
|
+
(:import [java.util Date]))
|
|
12
|
+
|
|
13
|
+
(set! *print-namespace-maps* false)
|
|
14
|
+
|
|
15
|
+
(def schema [{:db/ident :name
|
|
16
|
+
:db/valueType :db.type/string
|
|
17
|
+
:db/unique :db.unique/identity
|
|
18
|
+
:db/index true
|
|
19
|
+
:db/cardinality :db.cardinality/one}
|
|
20
|
+
{:db/ident :age
|
|
21
|
+
:db/valueType :db.type/long
|
|
22
|
+
:db/cardinality :db.cardinality/one}
|
|
23
|
+
{:name "Alice"
|
|
24
|
+
:age 25}
|
|
25
|
+
{:name "Bob"
|
|
26
|
+
:age 35}])
|
|
27
|
+
|
|
28
|
+
(def cfg-template {:store {:backend :memory
|
|
29
|
+
:id #uuid "00110000-0000-0000-0000-000000000011"}
|
|
30
|
+
:keep-history? true
|
|
31
|
+
:schema-flexibility :write
|
|
32
|
+
:initial-tx schema})
|
|
33
|
+
|
|
34
|
+
(defn now []
|
|
35
|
+
(Date.))
|
|
36
|
+
|
|
37
|
+
(defn permute-and-repeat [max-repeat elements]
|
|
38
|
+
(let [elements (vec elements)
|
|
39
|
+
n (count elements)]
|
|
40
|
+
(loop [stack [[[] (zipmap (range n) (repeat 0))]]
|
|
41
|
+
result []]
|
|
42
|
+
(if (empty? stack)
|
|
43
|
+
result
|
|
44
|
+
(let [[[fs freqs] & stack] stack]
|
|
45
|
+
(recur (into stack
|
|
46
|
+
(keep (fn [[index counter]]
|
|
47
|
+
(when (< counter max-repeat)
|
|
48
|
+
[(conj fs index) (update freqs index inc)])))
|
|
49
|
+
freqs)
|
|
50
|
+
(if (every? pos? (vals freqs))
|
|
51
|
+
(conj result (mapv #(nth elements %) fs))
|
|
52
|
+
result)))))))
|
|
53
|
+
|
|
54
|
+
(defn vary-db-ops [db & ops]
|
|
55
|
+
{:post [(seq %)
|
|
56
|
+
(<= (count ops) (count %))]}
|
|
57
|
+
(for [fs (permute-and-repeat 2 ops)]
|
|
58
|
+
((apply comp fs) db)))
|
|
59
|
+
|
|
60
|
+
(deftest test-base-history
|
|
61
|
+
(let [cfg (assoc-in cfg-template [:store :id] #uuid "71000000-0000-0000-0000-000000000001")
|
|
62
|
+
conn (setup-db cfg)
|
|
63
|
+
tx-id0 (:max-tx @conn)]
|
|
64
|
+
(testing "Initial data"
|
|
65
|
+
(is (= #{["Alice" 25] ["Bob" 35]}
|
|
66
|
+
(d/q '[:find ?n ?a :where [?e :name ?n] [?e :age ?a]] @conn))))
|
|
67
|
+
|
|
68
|
+
(testing "historical values"
|
|
69
|
+
(d/transact conn [{:db/id [:name "Alice"] :age 30}])
|
|
70
|
+
(are [x y]
|
|
71
|
+
(= x y)
|
|
72
|
+
#{[30]}
|
|
73
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]] @conn [:name "Alice"])
|
|
74
|
+
#{[30] [25]}
|
|
75
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]] (d/history @conn) [:name "Alice"])))
|
|
76
|
+
(testing "historical values after with retraction"
|
|
77
|
+
(let [tx-id1 (:max-tx @conn)
|
|
78
|
+
_ (d/transact conn [[:db/retractEntity [:name "Alice"]]])
|
|
79
|
+
tx-id2 (:max-tx @conn)]
|
|
80
|
+
(is (thrown-with-msg? Throwable #"Nothing found for entity id"
|
|
81
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]] @conn [:name "Alice"])))
|
|
82
|
+
|
|
83
|
+
(doseq [db (vary-db-ops @conn d/history)]
|
|
84
|
+
(is (= #{[30] [25]}
|
|
85
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]]
|
|
86
|
+
db
|
|
87
|
+
[:name "Alice"]))))
|
|
88
|
+
(doseq [db (vary-db-ops @conn d/history #(d/as-of % tx-id0))]
|
|
89
|
+
(is (= #{[25]}
|
|
90
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]]
|
|
91
|
+
db
|
|
92
|
+
[:name "Alice"]))))
|
|
93
|
+
(doseq [db (vary-db-ops @conn d/history #(d/since % tx-id1))]
|
|
94
|
+
(is (= #{[30]}
|
|
95
|
+
(d/q '[:find ?a :in $ ?e :where [?e :age ?a]]
|
|
96
|
+
db
|
|
97
|
+
[:name "Alice"]))))
|
|
98
|
+
|
|
99
|
+
(testing "find retracted values"
|
|
100
|
+
(doseq [db (vary-db-ops @conn d/history)]
|
|
101
|
+
(is (= #{["Alice" 25] ["Alice" 30]}
|
|
102
|
+
(d/q '[:find ?n ?a :where [?r :age ?a _ false] [?r :name ?n _ false]]
|
|
103
|
+
db)))))
|
|
104
|
+
(testing "find source transaction of retracted values"
|
|
105
|
+
(doseq [db (vary-db-ops @conn d/history)]
|
|
106
|
+
(is (= #{[25 true] [25 false] [30 true] [30 false]}
|
|
107
|
+
(d/q '[:find ?a ?op
|
|
108
|
+
:in $ ?e
|
|
109
|
+
:where
|
|
110
|
+
[?e :age ?a ?t ?op]
|
|
111
|
+
[?t :db/txInstant ?d]]
|
|
112
|
+
db
|
|
113
|
+
[:name "Alice"])))))))
|
|
114
|
+
(d/release conn)))
|
|
115
|
+
|
|
116
|
+
(defn replace-commit-id [s]
|
|
117
|
+
(clojure.string/replace s #":commit-id #uuid \"[^\"]+\"" ":commit-id :REPLACED"))
|
|
118
|
+
|
|
119
|
+
(deftest test-historical-queries
|
|
120
|
+
(let [cfg (-> cfg-template
|
|
121
|
+
(assoc-in [:store :id] #uuid "71000000-0000-0000-0000-000000000002"))
|
|
122
|
+
conn (setup-db cfg)]
|
|
123
|
+
|
|
124
|
+
(testing "get all values before specific time"
|
|
125
|
+
(let [_ (d/transact conn [{:db/id [:name "Alice"] :age 30}])
|
|
126
|
+
;; sleep to make sure that transact thread has older timestamp
|
|
127
|
+
_ (sleep 10)
|
|
128
|
+
date (now)
|
|
129
|
+
;; sleep to make sure that transact thread has newer timestamp
|
|
130
|
+
_ (sleep 10)
|
|
131
|
+
_ (d/transact conn [{:db/id [:name "Alice"] :age 35}])
|
|
132
|
+
history-db (d/history @conn)
|
|
133
|
+
current-db @conn
|
|
134
|
+
current-query '[:find ?a :in $ ?e :where [?e :age ?a]]
|
|
135
|
+
query '[:find ?a
|
|
136
|
+
:in $ ?e ?fd
|
|
137
|
+
:where
|
|
138
|
+
[?e :age ?a ?tx]
|
|
139
|
+
[?tx :db/txInstant ?t]
|
|
140
|
+
[(before? ?t ?fd)]]
|
|
141
|
+
query-with-< '[:find ?a
|
|
142
|
+
:in $ ?e ?fd
|
|
143
|
+
:where
|
|
144
|
+
[?e :age ?a ?tx]
|
|
145
|
+
[?tx :db/txInstant ?t]
|
|
146
|
+
[(< ?t ?fd)]]]
|
|
147
|
+
(is (= #{[35]}
|
|
148
|
+
(d/q current-query current-db [:name "Alice"])))
|
|
149
|
+
(is (= #{[25] [30]}
|
|
150
|
+
(d/q query history-db [:name "Alice"] date)))
|
|
151
|
+
(is (= #{[25] [30]}
|
|
152
|
+
(d/q query-with-< history-db [:name "Alice"] date)))))
|
|
153
|
+
(testing "print DB"
|
|
154
|
+
(is (= "#datahike/HistoricalDB {:origin #datahike/DB {:store-id [#uuid \"71000000-0000-0000-0000-000000000002\" :db] :commit-id :REPLACED :max-tx 536870915 :max-eid 4}}"
|
|
155
|
+
(replace-commit-id (pr-str (d/history @conn))))))
|
|
156
|
+
(d/release conn)))
|
|
157
|
+
|
|
158
|
+
(deftest test-as-of-db
|
|
159
|
+
(let [cfg (-> cfg-template
|
|
160
|
+
(assoc-in [:store :id] #uuid "71000000-0000-0000-0000-000000000003"))
|
|
161
|
+
conn (setup-db cfg)
|
|
162
|
+
first-date (now)
|
|
163
|
+
;; sleep to make sure that transact thread has newer timestamp
|
|
164
|
+
_ (sleep 10)
|
|
165
|
+
tx-id 536870914
|
|
166
|
+
query '[:find ?a :in $ ?e :where [?e :age ?a ?tx]]]
|
|
167
|
+
(testing "get values at specific time"
|
|
168
|
+
(is (= #{[25]}
|
|
169
|
+
(d/q query (d/as-of @conn first-date) [:name "Alice"]))))
|
|
170
|
+
(testing "use transaction ID"
|
|
171
|
+
(is (= #{[25]}
|
|
172
|
+
(d/q query (d/as-of @conn tx-id) [:name "Alice"]))))
|
|
173
|
+
(testing "print DB"
|
|
174
|
+
(let [as-of-str (pr-str (d/as-of @conn tx-id))
|
|
175
|
+
origin-str (pr-str (dbi/-origin (d/as-of @conn tx-id)))]
|
|
176
|
+
(is (= "#datahike/AsOfDB {:origin #datahike/DB {:store-id [#uuid \"71000000-0000-0000-0000-000000000003\" :db] :commit-id :REPLACED :max-tx 536870913 :max-eid 4} :time-point 536870914}"
|
|
177
|
+
(replace-commit-id as-of-str)))
|
|
178
|
+
(is (= "#datahike/DB {:store-id [#uuid \"71000000-0000-0000-0000-000000000003\" :db] :commit-id :REPLACED :max-tx 536870913 :max-eid 4}"
|
|
179
|
+
(replace-commit-id origin-str)))
|
|
180
|
+
(is (not= as-of-str origin-str))))
|
|
181
|
+
(testing "retraction"
|
|
182
|
+
(let [find-alices-age '[:find ?a :in $ ?n :where [?e :name ?n] [?e :age ?a]]]
|
|
183
|
+
(testing "before"
|
|
184
|
+
(is (= #{[25]}
|
|
185
|
+
(d/q find-alices-age (d/as-of @conn tx-id) "Alice"))))
|
|
186
|
+
(d/transact conn [[:db/retractEntity [:name "Alice"]]])
|
|
187
|
+
(testing "after"
|
|
188
|
+
(is (= #{}
|
|
189
|
+
(d/q find-alices-age (d/as-of @conn tx-id) "Alice"))))))
|
|
190
|
+
(d/release conn)))
|
|
191
|
+
|
|
192
|
+
(deftest test-since-db
|
|
193
|
+
(let [cfg (-> cfg-template
|
|
194
|
+
(assoc-in [:store :id] #uuid "71000000-0000-0000-0000-000000000004"))
|
|
195
|
+
conn (setup-db cfg)
|
|
196
|
+
first-date (now)
|
|
197
|
+
;; sleep to make sure that transact thread has newer timestamp
|
|
198
|
+
_ (sleep 10)
|
|
199
|
+
tx-id 536870913
|
|
200
|
+
query '[:find ?a :where [?e :age ?a]]]
|
|
201
|
+
(testing "empty after first insertion"
|
|
202
|
+
(is (= #{}
|
|
203
|
+
(d/q query (d/since @conn first-date)))))
|
|
204
|
+
(testing "added new value"
|
|
205
|
+
(let [new-age 30
|
|
206
|
+
_ (d/transact conn [{:db/id [:name "Alice"] :age new-age}])]
|
|
207
|
+
(is (= #{[new-age]}
|
|
208
|
+
(d/q query (d/since @conn first-date))))
|
|
209
|
+
(is (= #{[new-age]}
|
|
210
|
+
(d/q query (d/since @conn tx-id))))))
|
|
211
|
+
(testing "print DB"
|
|
212
|
+
(is (= "#datahike/SinceDB {:origin #datahike/DB {:store-id [#uuid \"71000000-0000-0000-0000-000000000004\" :db] :commit-id :REPLACED :max-tx 536870914 :max-eid 4} :time-point 536870913}"
|
|
213
|
+
(replace-commit-id (pr-str (d/since @conn tx-id))))))
|
|
214
|
+
(d/release conn)))
|
|
215
|
+
|
|
216
|
+
(deftest test-no-history
|
|
217
|
+
(let [initial-tx [{:db/ident :name
|
|
218
|
+
:db/cardinality :db.cardinality/one
|
|
219
|
+
:db/valueType :db.type/string
|
|
220
|
+
:db/unique :db.unique/identity}
|
|
221
|
+
{:db/ident :age
|
|
222
|
+
:db/cardinality :db.cardinality/one
|
|
223
|
+
:db/valueType :db.type/long
|
|
224
|
+
:db/noHistory true}
|
|
225
|
+
{:name "Alice" :age 25}
|
|
226
|
+
{:name "Bob" :age 35}]
|
|
227
|
+
cfg (-> cfg-template
|
|
228
|
+
(assoc-in [:store :id] #uuid "71000000-0000-0000-0000-000000000005")
|
|
229
|
+
(assoc :initial-tx initial-tx))
|
|
230
|
+
conn (setup-db cfg)
|
|
231
|
+
query '[:find ?n ?a :where [?e :name ?n] [?e :age ?a]]]
|
|
232
|
+
(testing "all names and ages are present in history"
|
|
233
|
+
(is (= #{["Alice" 25] ["Bob" 35]}
|
|
234
|
+
(d/q query (d/history @conn)))))
|
|
235
|
+
(d/transact conn [[:db/retractEntity [:name "Alice"]]])
|
|
236
|
+
(testing "no-history attributes are not present in history"
|
|
237
|
+
(is (= #{["Bob" 35]}
|
|
238
|
+
(d/q query (d/history @conn)))))
|
|
239
|
+
(testing "all other attributes are present in history"
|
|
240
|
+
(is (= #{["Alice"] ["Bob"]}
|
|
241
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/history @conn)))))
|
|
242
|
+
(d/release conn)))
|
|
243
|
+
|
|
244
|
+
(deftest upsert-history
|
|
245
|
+
(let [cfg {:store {:backend :memory
|
|
246
|
+
:id #uuid "00120000-0000-0000-0000-000000000012"}
|
|
247
|
+
:keep-history? true
|
|
248
|
+
:schema-flexibility :read
|
|
249
|
+
:initial-tx schema}
|
|
250
|
+
conn (setup-db cfg)
|
|
251
|
+
query '[:find ?a ?t ?op
|
|
252
|
+
:where
|
|
253
|
+
[?e :name "Alice"]
|
|
254
|
+
[?e :age ?a ?t ?op]]]
|
|
255
|
+
(testing "add history datoms without upsert operation happening"
|
|
256
|
+
(let [datoms (d/datoms (d/history @conn) {:index :aevt :components [:age [:name "Alice"]]})
|
|
257
|
+
xf (map (comp vec seq))]
|
|
258
|
+
(is (= [[(+ const/e0 3) :age 25 (+ const/tx0 1) true]]
|
|
259
|
+
(into [] xf datoms)))))
|
|
260
|
+
(testing "upsert entity"
|
|
261
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 30]])
|
|
262
|
+
(is (= #{[30 (+ const/tx0 2) true]}
|
|
263
|
+
(d/q query @conn)))
|
|
264
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
265
|
+
[25 (+ const/tx0 2) false]
|
|
266
|
+
[30 (+ const/tx0 2) true]}
|
|
267
|
+
(d/q query (d/history @conn)))))
|
|
268
|
+
(testing "second upsert"
|
|
269
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 35]])
|
|
270
|
+
(is (= #{[35 (+ const/tx0 3) true]}
|
|
271
|
+
(d/q query @conn)))
|
|
272
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
273
|
+
[25 (+ const/tx0 2) false]
|
|
274
|
+
[30 (+ const/tx0 2) true]
|
|
275
|
+
[30 (+ const/tx0 3) false]
|
|
276
|
+
[35 (+ const/tx0 3) true]}
|
|
277
|
+
(d/q query (d/history @conn)))))
|
|
278
|
+
(testing "re-insert previous value"
|
|
279
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 25]])
|
|
280
|
+
(is (= #{[25 (+ const/tx0 4) true]}
|
|
281
|
+
(d/q query @conn)))
|
|
282
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
283
|
+
[25 (+ const/tx0 2) false]
|
|
284
|
+
[30 (+ const/tx0 2) true]
|
|
285
|
+
[30 (+ const/tx0 3) false]
|
|
286
|
+
[35 (+ const/tx0 3) true]
|
|
287
|
+
[35 (+ const/tx0 4) false]
|
|
288
|
+
[25 (+ const/tx0 4) true]}
|
|
289
|
+
(d/q query (d/history @conn)))))
|
|
290
|
+
(testing "retract upserted values"
|
|
291
|
+
(d/transact conn [[:db/retract [:name "Alice"] :age 25]])
|
|
292
|
+
(is (= #{}
|
|
293
|
+
(d/q query @conn)))
|
|
294
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
295
|
+
[25 (+ const/tx0 2) false]
|
|
296
|
+
[30 (+ const/tx0 2) true]
|
|
297
|
+
[30 (+ const/tx0 3) false]
|
|
298
|
+
[35 (+ const/tx0 3) true]
|
|
299
|
+
[35 (+ const/tx0 4) false]
|
|
300
|
+
[25 (+ const/tx0 4) true]
|
|
301
|
+
[25 (+ const/tx0 5) false]}
|
|
302
|
+
(d/q query (d/history @conn)))))
|
|
303
|
+
(testing "historical eavt datoms"
|
|
304
|
+
(is (= #{[1 :db/cardinality :db.cardinality/one 536870913 true]
|
|
305
|
+
[1 :db/ident :name 536870913 true]
|
|
306
|
+
[1 :db/index true 536870913 true]
|
|
307
|
+
[1 :db/unique :db.unique/identity 536870913 true]
|
|
308
|
+
[1 :db/valueType :db.type/string 536870913 true]
|
|
309
|
+
[2 :db/cardinality :db.cardinality/one 536870913 true]
|
|
310
|
+
[2 :db/ident :age 536870913 true]
|
|
311
|
+
[2 :db/valueType :db.type/long 536870913 true]
|
|
312
|
+
[3 :age 25 536870913 true]
|
|
313
|
+
[3 :age 25 536870914 false]
|
|
314
|
+
[3 :age 25 536870916 true]
|
|
315
|
+
[3 :age 25 536870917 false]
|
|
316
|
+
[3 :age 30 536870914 true]
|
|
317
|
+
[3 :age 30 536870915 false]
|
|
318
|
+
[3 :age 35 536870915 true]
|
|
319
|
+
[3 :age 35 536870916 false]
|
|
320
|
+
[3 :name "Alice" 536870913 true]
|
|
321
|
+
[4 :age 35 536870913 true]
|
|
322
|
+
[4 :name "Bob" 536870913 true]}
|
|
323
|
+
(->> (d/datoms (d/history @conn) {:index :eavt :components nil})
|
|
324
|
+
(map (comp vec seq))
|
|
325
|
+
(remove (fn [[e _ _ _]]
|
|
326
|
+
(< const/tx0 e)))
|
|
327
|
+
set))))
|
|
328
|
+
(testing "historical aevt datoms"
|
|
329
|
+
(is (= #{[3 :age 25 536870913 true]
|
|
330
|
+
[3 :age 25 536870914 false]
|
|
331
|
+
[3 :age 25 536870916 true]
|
|
332
|
+
[3 :age 25 536870917 false]
|
|
333
|
+
[3 :age 30 536870914 true]
|
|
334
|
+
[3 :age 30 536870915 false]
|
|
335
|
+
[3 :age 35 536870915 true]
|
|
336
|
+
[3 :age 35 536870916 false]
|
|
337
|
+
[4 :age 35 536870913 true]
|
|
338
|
+
[3 :name "Alice" 536870913 true]
|
|
339
|
+
[4 :name "Bob" 536870913 true]
|
|
340
|
+
[1 :db/cardinality :db.cardinality/one 536870913 true]
|
|
341
|
+
[2 :db/cardinality :db.cardinality/one 536870913 true]
|
|
342
|
+
[1 :db/ident :name 536870913 true]
|
|
343
|
+
[2 :db/ident :age 536870913 true]
|
|
344
|
+
[1 :db/index true 536870913 true]
|
|
345
|
+
[1 :db/unique :db.unique/identity 536870913 true]
|
|
346
|
+
[1 :db/valueType :db.type/string 536870913 true]
|
|
347
|
+
[2 :db/valueType :db.type/long 536870913 true]}
|
|
348
|
+
(->> (d/datoms (d/history @conn) {:index :aevt :components nil})
|
|
349
|
+
(map (comp vec seq))
|
|
350
|
+
(remove (fn [[e _ _ _]]
|
|
351
|
+
(< const/tx0 e)))
|
|
352
|
+
set))))
|
|
353
|
+
(testing "historical avet datoms"
|
|
354
|
+
(is (= #{[3 :name "Alice" 536870913 true]
|
|
355
|
+
[4 :name "Bob" 536870913 true]
|
|
356
|
+
[2 :db/ident :age 536870913 true]
|
|
357
|
+
[1 :db/ident :name 536870913 true]}
|
|
358
|
+
(->> (d/datoms (d/history @conn) {:index :avet :components nil})
|
|
359
|
+
(map (comp vec seq))
|
|
360
|
+
(remove (fn [[e _ _ _]]
|
|
361
|
+
(< const/tx0 e)))
|
|
362
|
+
set))))
|
|
363
|
+
(testing "Datoms extracted like Wanderung does it"
|
|
364
|
+
(let [datoms (du/get-all-datoms @conn (map du/unmap-tx-timestamp))]
|
|
365
|
+
(is (= [[536870913 :db/txInstant :timestamp 536870913 true]
|
|
366
|
+
[1 :db/unique :db.unique/identity 536870913 true]
|
|
367
|
+
[1 :db/ident :name 536870913 true]
|
|
368
|
+
[1 :db/valueType :db.type/string 536870913 true]
|
|
369
|
+
[1 :db/index true 536870913 true]
|
|
370
|
+
[1 :db/cardinality :db.cardinality/one 536870913 true]
|
|
371
|
+
[2 :db/valueType :db.type/long 536870913 true]
|
|
372
|
+
[2 :db/cardinality :db.cardinality/one 536870913 true]
|
|
373
|
+
[2 :db/ident :age 536870913 true]
|
|
374
|
+
[3 :name "Alice" 536870913 true]
|
|
375
|
+
[3 :age 25 536870913 true]
|
|
376
|
+
[4 :age 35 536870913 true]
|
|
377
|
+
[4 :name "Bob" 536870913 true]
|
|
378
|
+
[536870914 :db/txInstant :timestamp 536870914 true]
|
|
379
|
+
[3 :age 25 536870914 false]
|
|
380
|
+
[3 :age 30 536870914 true]
|
|
381
|
+
[536870915 :db/txInstant :timestamp 536870915 true]
|
|
382
|
+
[3 :age 30 536870915 false]
|
|
383
|
+
[3 :age 35 536870915 true]
|
|
384
|
+
[536870916 :db/txInstant :timestamp 536870916 true]
|
|
385
|
+
[3 :age 35 536870916 false]
|
|
386
|
+
[3 :age 25 536870916 true]
|
|
387
|
+
[536870917 :db/txInstant :timestamp 536870917 true]
|
|
388
|
+
[3 :age 25 536870917 false]]
|
|
389
|
+
datoms))))))
|
|
390
|
+
|
|
391
|
+
(deftest test-no-duplicates-on-history-search
|
|
392
|
+
(let [schema [{:db/ident :name
|
|
393
|
+
:db/cardinality :db.cardinality/one
|
|
394
|
+
:db/index true
|
|
395
|
+
:db/unique :db.unique/identity
|
|
396
|
+
:db/valueType :db.type/string}
|
|
397
|
+
{:db/ident :sibling
|
|
398
|
+
:db/cardinality :db.cardinality/many
|
|
399
|
+
:db/valueType :db.type/ref}
|
|
400
|
+
{:db/ident :age
|
|
401
|
+
:db/cardinality :db.cardinality/one
|
|
402
|
+
:db/valueType :db.type/long}]
|
|
403
|
+
cfg {:store {:backend :memory :id #uuid "00130000-0000-0000-0000-000000000013"}
|
|
404
|
+
:keep-history? true
|
|
405
|
+
:schema-flexibility :write
|
|
406
|
+
:attribute-refs? false}
|
|
407
|
+
conn (do
|
|
408
|
+
(d/delete-database cfg)
|
|
409
|
+
(d/create-database cfg)
|
|
410
|
+
(d/connect cfg))]
|
|
411
|
+
|
|
412
|
+
(d/transact conn schema)
|
|
413
|
+
(d/transact conn [{:name "Alice"
|
|
414
|
+
:age 25}
|
|
415
|
+
{:name "Charlie"
|
|
416
|
+
:age 45
|
|
417
|
+
:sibling [[:name "Alice"] [:name "Charlie"]]}])
|
|
418
|
+
(is (= 1 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :name "Alice"))))
|
|
419
|
+
(is (= 1 (count (filter :added (d/datoms (d/history @conn) :eavt [:name "Alice"] :name "Alice")))))
|
|
420
|
+
|
|
421
|
+
(d/release conn)
|
|
422
|
+
(d/delete-database cfg)))
|
|
423
|
+
;; => #'datahike.test.time-variance/test-no-duplicates-with-cardinality-many
|
|
424
|
+
|
|
425
|
+
;; https://github.com/replikativ/datahike/issues/470
|
|
426
|
+
(deftest test-history-record-attribute-access
|
|
427
|
+
(let [cfg {:store {:backend :memory :id (random-uuid)}
|
|
428
|
+
:keep-history? true
|
|
429
|
+
:schema-flexibility :read
|
|
430
|
+
:attribute-refs? false}
|
|
431
|
+
conn (setup-db cfg)
|
|
432
|
+
{{:keys [db/current-tx]} :tempids} (d/transact conn [{:name "Anne"}])
|
|
433
|
+
_ (d/transact conn [{:name "Bernard"}])
|
|
434
|
+
db @conn]
|
|
435
|
+
(testing "history db attributes"
|
|
436
|
+
(is (= db (:origin-db (d/history db))))
|
|
437
|
+
(is (= (:eavt db) (-> db d/history :origin-db :eavt))))
|
|
438
|
+
(testing "as-of db attributes"
|
|
439
|
+
(is (= db (:origin-db (d/as-of db current-tx))))
|
|
440
|
+
(is (= current-tx (:time-point (d/as-of db current-tx))))
|
|
441
|
+
(is (= (:eavt db) (-> db (d/as-of current-tx) :origin-db :eavt))))
|
|
442
|
+
(testing "since db attributes"
|
|
443
|
+
(is (= db (:origin-db (d/since db current-tx))))
|
|
444
|
+
(is (= current-tx (:time-point (d/since db current-tx))))
|
|
445
|
+
(is (= (:eavt db) (-> db (d/since current-tx) :origin-db :eavt))))
|
|
446
|
+
(d/release conn)))
|
|
447
|
+
|
|
448
|
+
(deftest test-filter-current-values-of-same-transaction
|
|
449
|
+
(let [keyword-cfg {:store {:backend :memory :id (random-uuid)}
|
|
450
|
+
:keep-history? true
|
|
451
|
+
:schema-flexibility :write
|
|
452
|
+
:attribute-refs? false}
|
|
453
|
+
name-schema {:db/ident :name
|
|
454
|
+
:db/cardinality :db.cardinality/one
|
|
455
|
+
:db/unique :db.unique/identity
|
|
456
|
+
:db/valueType :db.type/string}]
|
|
457
|
+
(testing "cardinality one"
|
|
458
|
+
(let [schema [name-schema
|
|
459
|
+
{:db/ident :aka
|
|
460
|
+
:db/cardinality :db.cardinality/one
|
|
461
|
+
:db/valueType :db.type/string}]
|
|
462
|
+
conn (setup-db keyword-cfg)
|
|
463
|
+
_ (d/transact conn schema)
|
|
464
|
+
{:keys [tx-data] :as _tx-report} (d/transact conn [{:name "Michal" :aka "Tupen"}])
|
|
465
|
+
michal (:e (first (filter #(= "Michal" (:v %)) tx-data)))
|
|
466
|
+
{{:keys [db/current-tx]} :tempids} (d/transact conn [[:db/retract michal :aka "Tupen"]
|
|
467
|
+
[:db/add michal :aka "Devil"]
|
|
468
|
+
[:db/retract michal :aka "Tupen"]])
|
|
469
|
+
_ (d/transact conn [[:db/retract michal :aka "Devil"]])
|
|
470
|
+
as-of-db (d/as-of @conn current-tx)]
|
|
471
|
+
(is (= {:aka "Devil"}
|
|
472
|
+
(d/pull as-of-db [:aka] michal)))
|
|
473
|
+
(is (= nil
|
|
474
|
+
(d/pull @conn [:aka] michal)))
|
|
475
|
+
(d/release conn)))
|
|
476
|
+
(testing "cardinality many"
|
|
477
|
+
(testing "keyword attributes"
|
|
478
|
+
(let [schema [name-schema
|
|
479
|
+
{:db/ident :aka
|
|
480
|
+
:db/cardinality :db.cardinality/many
|
|
481
|
+
:db/valueType :db.type/string}]
|
|
482
|
+
conn (setup-db keyword-cfg)
|
|
483
|
+
_ (d/transact conn schema)
|
|
484
|
+
{:keys [tx-data]} (d/transact conn [{:name "Michal" :aka "Tupen"}])
|
|
485
|
+
michal (:e (first (filter #(= "Michal" (:v %)) tx-data)))
|
|
486
|
+
{{:keys [db/current-tx]} :tempids} (d/transact conn [[:db/retract michal :aka "Tupen"]
|
|
487
|
+
[:db/add michal :aka "Devil"]
|
|
488
|
+
[:db/retract michal :aka "Tupen"]])
|
|
489
|
+
_ (d/transact conn [[:db/retract michal :aka "Devil"]])
|
|
490
|
+
as-of-db (d/as-of @conn current-tx)]
|
|
491
|
+
(is (= {:aka ["Devil"]}
|
|
492
|
+
(d/pull as-of-db [:aka] michal)))
|
|
493
|
+
(is (= nil
|
|
494
|
+
(d/pull @conn [:aka] michal)))
|
|
495
|
+
(d/release conn)))
|
|
496
|
+
|
|
497
|
+
(testing "reference attributes show all options"
|
|
498
|
+
(let [schema [name-schema
|
|
499
|
+
{:db/ident :aka
|
|
500
|
+
:db/cardinality :db.cardinality/many
|
|
501
|
+
:db/valueType :db.type/string}]
|
|
502
|
+
conn (setup-db (assoc keyword-cfg :attribute-refs? true))
|
|
503
|
+
_ (d/transact conn schema)
|
|
504
|
+
{tx-data :tx-data
|
|
505
|
+
{:keys [db/current-tx]} :tempids} (d/transact conn [{:name "Michal" :aka ["Tupen" "Devil"]}])
|
|
506
|
+
michal (:e (first (filter #(= "Michal" (:v %)) tx-data)))
|
|
507
|
+
as-of-db (d/as-of @conn current-tx)]
|
|
508
|
+
(is (= {:aka ["Devil" "Tupen"]}
|
|
509
|
+
(d/pull as-of-db [:aka] michal)))
|
|
510
|
+
(d/release conn))))))
|
|
511
|
+
|
|
512
|
+
;; https://github.com/replikativ/datahike/issues/572
|
|
513
|
+
(deftest as-of-should-fail-on-invalid-time-points
|
|
514
|
+
(let [cfg (assoc-in cfg-template [:store :id] #uuid "71000000-0000-0000-0000-000000000006")
|
|
515
|
+
conn (setup-db cfg)]
|
|
516
|
+
(is (thrown-with-msg? Throwable #"Invalid transaction ID. Must be bigger than 536870912."
|
|
517
|
+
(d/as-of @conn 42)))
|
|
518
|
+
(d/release conn)))
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
(ns datahike.test.tools-test
|
|
2
|
+
(:require [datahike.tools :as dt]
|
|
3
|
+
[clojure.test :refer :all]))
|
|
4
|
+
|
|
5
|
+
(deftest test-with-destructured-vector
|
|
6
|
+
(is (= [11 19]
|
|
7
|
+
(dt/with-destructured-vector [10 20]
|
|
8
|
+
a (inc a)
|
|
9
|
+
b (dec b))))
|
|
10
|
+
(is (= [11]
|
|
11
|
+
(dt/with-destructured-vector [10]
|
|
12
|
+
a (inc a)
|
|
13
|
+
b (+ a b))))
|
|
14
|
+
(is (= [300 40]
|
|
15
|
+
(dt/with-destructured-vector [10 30]
|
|
16
|
+
a (* a b)
|
|
17
|
+
b (+ a b))))
|
|
18
|
+
(is (= [100 400]
|
|
19
|
+
(dt/with-destructured-vector [10 20]
|
|
20
|
+
a (* a a)
|
|
21
|
+
b (* b b)
|
|
22
|
+
c (throw (ex-info "This element should not be evaluated" {}))))))
|
|
23
|
+
|
|
24
|
+
(defn add-resolver [context [result-var a b]]
|
|
25
|
+
(when (and (contains? context a)
|
|
26
|
+
(contains? context b))
|
|
27
|
+
(assoc context result-var (+ (context a)
|
|
28
|
+
(context b)))))
|
|
29
|
+
|
|
30
|
+
(deftest resolve-clauses-test
|
|
31
|
+
(is (= {:x 9 :y 10 :z 19 :w 28}
|
|
32
|
+
(dt/resolve-clauses add-resolver
|
|
33
|
+
{:x 9 :y 10}
|
|
34
|
+
[[:w :z :x]
|
|
35
|
+
[:z :x :y]])))
|
|
36
|
+
(is (= {:x 9 :y 10 :z 19 :w 28}
|
|
37
|
+
(dt/resolve-clauses add-resolver
|
|
38
|
+
{:x 9 :y 10}
|
|
39
|
+
[[:z :x :y]
|
|
40
|
+
[:w :z :x]])))
|
|
41
|
+
(is (thrown? Exception
|
|
42
|
+
(dt/resolve-clauses add-resolver
|
|
43
|
+
{:x 9 :y 10}
|
|
44
|
+
[[:w :z :x]]))))
|
|
45
|
+
|
|
46
|
+
(deftest group-by-step-test
|
|
47
|
+
(is (= {true [1000 1002 1004 1006 1008]
|
|
48
|
+
false [1001 1003 1005 1007 1009]}
|
|
49
|
+
(transduce (map #(+ 1000 %))
|
|
50
|
+
(dt/group-by-step even?)
|
|
51
|
+
(range 10)))))
|
|
52
|
+
|
|
53
|
+
(deftest test-match-vector
|
|
54
|
+
(is (= 0 (dt/match-vector [nil nil]
|
|
55
|
+
[_ _] 0
|
|
56
|
+
[_ 1] 1
|
|
57
|
+
[1 *] 2)))
|
|
58
|
+
(is (= 1 (dt/match-vector [nil 9]
|
|
59
|
+
[_ _] 0
|
|
60
|
+
[_ 1] 1
|
|
61
|
+
[1 *] 2)))
|
|
62
|
+
(is (= 2 (dt/match-vector [10 nil]
|
|
63
|
+
[_ _] 0
|
|
64
|
+
[_ 1] 1
|
|
65
|
+
[1 *] 2)))
|
|
66
|
+
(is (= 2 (dt/match-vector [10 :asdf]
|
|
67
|
+
[_ _] 0
|
|
68
|
+
[_ 1] 1
|
|
69
|
+
[1 *] 2)))
|
|
70
|
+
(is (= 3 (dt/match-vector [10 :asdf]
|
|
71
|
+
[_ _] 0
|
|
72
|
+
[_ 1] 1
|
|
73
|
+
[1 _] 2
|
|
74
|
+
[1 1] 3)))
|
|
75
|
+
(is (= 2 (dt/match-vector [10 nil]
|
|
76
|
+
[_ _] 0
|
|
77
|
+
[_ 1] 1
|
|
78
|
+
[1 _] 2
|
|
79
|
+
[1 1] 3))))
|
|
80
|
+
|
|
81
|
+
(defmacro wrap-range-tree [input-symbol]
|
|
82
|
+
(dt/range-subset-tree 3 input-symbol (fn [x y] [:inds x :mask y])))
|
|
83
|
+
|
|
84
|
+
(deftest range-subset-tree-test
|
|
85
|
+
(is (= (dt/range-subset-tree 1 'x (fn [inds _] [:inds inds]))
|
|
86
|
+
'(if
|
|
87
|
+
(clojure.core/empty? x)
|
|
88
|
+
[:inds []]
|
|
89
|
+
(if
|
|
90
|
+
(clojure.core/= 0 (clojure.core/first x))
|
|
91
|
+
(clojure.core/let [x (clojure.core/rest x)] [:inds [0]])
|
|
92
|
+
[:inds []]))))
|
|
93
|
+
(is (= [:inds [1 2] :mask [nil 0 1]]
|
|
94
|
+
(wrap-range-tree [1 2])))
|
|
95
|
+
(is (= [:inds [1] :mask [nil 0 nil]]
|
|
96
|
+
(wrap-range-tree [1])))
|
|
97
|
+
(is (= [:inds [0 2] :mask [0 nil 1]]
|
|
98
|
+
(wrap-range-tree [0 2]))))
|
|
99
|
+
|
|
100
|
+
(deftest merge-distinct-sorted-seqs-test
|
|
101
|
+
(testing "Custom comparator"
|
|
102
|
+
(let [m {:one 1
|
|
103
|
+
:two 2
|
|
104
|
+
:three 3
|
|
105
|
+
:four 4
|
|
106
|
+
:five 5
|
|
107
|
+
:six 6
|
|
108
|
+
:seven 7
|
|
109
|
+
:eight 8
|
|
110
|
+
:nine 9
|
|
111
|
+
:ten 10}
|
|
112
|
+
cmp (fn [a b] (compare (m a) (m b)))]
|
|
113
|
+
(is (= [] (dt/merge-distinct-sorted-seqs cmp [] [])))
|
|
114
|
+
(is (= [:one] (dt/merge-distinct-sorted-seqs cmp [:one] [])))
|
|
115
|
+
(is (= [:one] (dt/merge-distinct-sorted-seqs cmp [:one] [:one])))
|
|
116
|
+
(is (= [:one] (dt/merge-distinct-sorted-seqs cmp [] [:one])))
|
|
117
|
+
(is (= [:one :two] (dt/merge-distinct-sorted-seqs cmp [:two] [:one])))
|
|
118
|
+
(is (= [:one :two :three :four :five :nine :ten]
|
|
119
|
+
(dt/merge-distinct-sorted-seqs cmp
|
|
120
|
+
[:one :two :three :nine :ten]
|
|
121
|
+
[:two :three :four :five])))
|
|
122
|
+
(is (dt/distinct-sorted-seq? cmp []))
|
|
123
|
+
(is (dt/distinct-sorted-seq? cmp [:one]))
|
|
124
|
+
(is (dt/distinct-sorted-seq? cmp [:one :two]))
|
|
125
|
+
(is (dt/distinct-sorted-seq? cmp [:one :two :three]))
|
|
126
|
+
(is (not (dt/distinct-sorted-seq? cmp [:one :two :three :three])))
|
|
127
|
+
(is (not (dt/distinct-sorted-seq? cmp [:one :one :two :three])))
|
|
128
|
+
(is (not (dt/distinct-sorted-seq? cmp [:one :two :two :three])))
|
|
129
|
+
(is (not (dt/distinct-sorted-seq? cmp [:one :two :three :five :four])))))
|
|
130
|
+
(testing "Infinite length sequences"
|
|
131
|
+
(let [evens (iterate #(+ 2 %) 0)
|
|
132
|
+
odds (iterate #(+ 2 %) 1)
|
|
133
|
+
result (dt/merge-distinct-sorted-seqs compare odds evens)]
|
|
134
|
+
(is (= (range 1000) (take 1000 result))))))
|