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,86 @@
|
|
|
1
|
+
(ns datahike.test.http.writer-test
|
|
2
|
+
(:require
|
|
3
|
+
[clojure.test :as t :refer [is deftest testing]]
|
|
4
|
+
[datahike.http.server :refer [start-server stop-server]]
|
|
5
|
+
[datahike.http.writer]
|
|
6
|
+
[datahike.api :as d]))
|
|
7
|
+
|
|
8
|
+
(deftest test-http-writer
|
|
9
|
+
(testing "Testing distributed datahike.http.writer implementation."
|
|
10
|
+
(let [port 31283
|
|
11
|
+
server (start-server {:port port
|
|
12
|
+
:join? false
|
|
13
|
+
:dev-mode false
|
|
14
|
+
:token "securerandompassword"})]
|
|
15
|
+
(try
|
|
16
|
+
(let [cfg {:store {:backend :file
|
|
17
|
+
:path "/tmp/distributed_writer"
|
|
18
|
+
:id #uuid "17100000-0000-0000-0000-000000000001"}
|
|
19
|
+
:keep-history? true
|
|
20
|
+
:schema-flexibility :read
|
|
21
|
+
:writer {:backend :datahike-server
|
|
22
|
+
:url (str "http://localhost:" port)
|
|
23
|
+
:token "securerandompassword"}}
|
|
24
|
+
conn (do
|
|
25
|
+
(when (d/database-exists? cfg)
|
|
26
|
+
(d/delete-database cfg))
|
|
27
|
+
(d/create-database cfg)
|
|
28
|
+
(d/connect cfg))]
|
|
29
|
+
|
|
30
|
+
(d/transact conn [{:name "Alice"
|
|
31
|
+
:age 25}])
|
|
32
|
+
(is (= #{[25 "Alice"]}
|
|
33
|
+
(d/q '[:find ?a ?v
|
|
34
|
+
:in $ ?a
|
|
35
|
+
:where
|
|
36
|
+
[?e :name ?v]
|
|
37
|
+
[?e :age ?a]]
|
|
38
|
+
@conn
|
|
39
|
+
25)))
|
|
40
|
+
|
|
41
|
+
(d/transact conn [{:name "Peter"
|
|
42
|
+
:age 18}])
|
|
43
|
+
(is (= #{[18 "Peter"]}
|
|
44
|
+
(d/q '[:find ?a ?v
|
|
45
|
+
:in $ ?a
|
|
46
|
+
:where
|
|
47
|
+
[?e :name ?v]
|
|
48
|
+
[?e :age ?a]]
|
|
49
|
+
@conn
|
|
50
|
+
18)))
|
|
51
|
+
|
|
52
|
+
(d/delete-database cfg))
|
|
53
|
+
(finally
|
|
54
|
+
(stop-server server))))))
|
|
55
|
+
|
|
56
|
+
(deftest test-http-writer-failure-without-server
|
|
57
|
+
(testing "Db creation fails without writer connection."
|
|
58
|
+
(let [port 38217
|
|
59
|
+
cfg {:store {:backend :memory :id #uuid "00170000-0000-0000-0000-000000000017"}
|
|
60
|
+
:keep-history? true
|
|
61
|
+
:schema-flexibility :read
|
|
62
|
+
:writer {:backend :datahike-server
|
|
63
|
+
:url (str "http://localhost:" port)
|
|
64
|
+
:token "securerandompassword"}}]
|
|
65
|
+
(is (thrown? Exception
|
|
66
|
+
(do
|
|
67
|
+
(d/delete-database cfg)
|
|
68
|
+
(d/create-database cfg)
|
|
69
|
+
(d/connect cfg))))))
|
|
70
|
+
(testing "Transact fails without writer connection."
|
|
71
|
+
(let [port 38217
|
|
72
|
+
cfg {:store {:backend :memory :id #uuid "00180000-0000-0000-0000-000000000018"}
|
|
73
|
+
:keep-history? true
|
|
74
|
+
:schema-flexibility :read
|
|
75
|
+
:writer {:backend :datahike-server
|
|
76
|
+
:url (str "http://localhost:" port)
|
|
77
|
+
:token "securerandompassword"}}
|
|
78
|
+
server-cfg {:store {:backend :memory :id #uuid "00180000-0000-0000-0000-000000000018"}
|
|
79
|
+
:keep-history? true
|
|
80
|
+
:schema-flexibility :read}]
|
|
81
|
+
;; make sure the database exists before testing transact
|
|
82
|
+
(do (d/delete-database server-cfg)
|
|
83
|
+
(d/create-database server-cfg))
|
|
84
|
+
(is (thrown? Exception
|
|
85
|
+
(d/transact (d/connect cfg)
|
|
86
|
+
[{:name "Should fail."}]))))))
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
(ns datahike.test.ident-test
|
|
2
|
+
(:require
|
|
3
|
+
[clojure.test :as t :refer [is deftest]]
|
|
4
|
+
[datahike.api :as d]
|
|
5
|
+
[datahike.db :as db]))
|
|
6
|
+
|
|
7
|
+
(def db
|
|
8
|
+
(-> (db/empty-db {:ref {:db/valueType :db.type/ref}})
|
|
9
|
+
(d/db-with [[:db/add 1 :db/ident :ent1]
|
|
10
|
+
[:db/add 2 :db/ident :ent2]
|
|
11
|
+
[:db/add 2 :ref 1]])))
|
|
12
|
+
|
|
13
|
+
(deftest test-q
|
|
14
|
+
(is (= 1 (d/q '[:find ?v .
|
|
15
|
+
:where [:ent2 :ref ?v]] db)))
|
|
16
|
+
(is (= 2 (d/q '[:find ?f .
|
|
17
|
+
:where [?f :ref :ent1]] db))))
|
|
18
|
+
|
|
19
|
+
(deftest test-transact!
|
|
20
|
+
(let [db' (d/db-with db [[:db/add :ent1 :ref :ent2]])]
|
|
21
|
+
(is (= 2 (-> (d/entity db' :ent1) :ref :db/id)))))
|
|
22
|
+
|
|
23
|
+
(deftest test-entity
|
|
24
|
+
(is (= {:db/ident :ent1}
|
|
25
|
+
(into {} (d/entity db :ent1)))))
|
|
26
|
+
|
|
27
|
+
(deftest test-pull
|
|
28
|
+
(is (= {:db/id 1, :db/ident :ent1}
|
|
29
|
+
(d/pull db '[*] :ent1))))
|
|
30
|
+
|
|
31
|
+
#_(user/test-var #'test-transact!)
|
|
32
|
+
#_(t/test-ns 'datahike.test.ident)
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
(ns datahike.test.index-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.constants :refer [e0 tx0 emax txmax]]
|
|
7
|
+
[datahike.datom :as dd]
|
|
8
|
+
[datahike.db :as db]
|
|
9
|
+
[datahike.index :as di]
|
|
10
|
+
[datahike.index.persistent-set :as pset]
|
|
11
|
+
[org.replikativ.persistent-sorted-set :as psset]))
|
|
12
|
+
|
|
13
|
+
(deftest test-datoms
|
|
14
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
15
|
+
db (-> (db/empty-db {:age {:db/index true}})
|
|
16
|
+
(d/db-with [[:db/add 1 :name "Petr"]
|
|
17
|
+
[:db/add 1 :age 44]
|
|
18
|
+
[:db/add 2 :name "Ivan"]
|
|
19
|
+
[:db/add 2 :age 25]
|
|
20
|
+
[:db/add 3 :name "Sergey"]
|
|
21
|
+
[:db/add 3 :age 11]]))]
|
|
22
|
+
(testing "Main indexes, sort order"
|
|
23
|
+
(is (= [[1 :age 44]
|
|
24
|
+
[2 :age 25]
|
|
25
|
+
[3 :age 11]
|
|
26
|
+
[1 :name "Petr"]
|
|
27
|
+
[2 :name "Ivan"]
|
|
28
|
+
[3 :name "Sergey"]]
|
|
29
|
+
(map dvec (d/datoms db :aevt))))
|
|
30
|
+
|
|
31
|
+
(is (= [[1 :age 44]
|
|
32
|
+
[1 :name "Petr"]
|
|
33
|
+
[2 :age 25]
|
|
34
|
+
[2 :name "Ivan"]
|
|
35
|
+
[3 :age 11]
|
|
36
|
+
[3 :name "Sergey"]]
|
|
37
|
+
(map dvec (d/datoms db :eavt))))
|
|
38
|
+
|
|
39
|
+
(is (= [[3 :age 11]
|
|
40
|
+
[2 :age 25]
|
|
41
|
+
[1 :age 44]]
|
|
42
|
+
(map dvec (d/datoms db :avet))))) ;; name non-indexed, excluded from avet
|
|
43
|
+
|
|
44
|
+
(testing "Components filtration"
|
|
45
|
+
(is (= [[1 :age 44]
|
|
46
|
+
[1 :name "Petr"]]
|
|
47
|
+
(map dvec (d/datoms db :eavt 1))))
|
|
48
|
+
|
|
49
|
+
(is (= [[1 :age 44]]
|
|
50
|
+
(map dvec (d/datoms db :eavt 1 :age))))
|
|
51
|
+
|
|
52
|
+
(is (= [[3 :age 11]
|
|
53
|
+
[2 :age 25]
|
|
54
|
+
[1 :age 44]]
|
|
55
|
+
(map dvec (d/datoms db :avet :age)))))))
|
|
56
|
+
|
|
57
|
+
(deftest test-seek-datoms
|
|
58
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
59
|
+
db (-> (db/empty-db {:name {:db/index true}
|
|
60
|
+
:age {:db/index true}})
|
|
61
|
+
(d/db-with [[:db/add 1 :name "Petr"]
|
|
62
|
+
[:db/add 1 :age 44]
|
|
63
|
+
[:db/add 2 :name "Ivan"]
|
|
64
|
+
[:db/add 2 :age 25]
|
|
65
|
+
[:db/add 3 :name "Sergey"]
|
|
66
|
+
[:db/add 3 :age 11]]))]
|
|
67
|
+
|
|
68
|
+
(testing "Non-termination"
|
|
69
|
+
(is (= (map dvec (d/seek-datoms db :avet :age 10))
|
|
70
|
+
[[3 :age 11]
|
|
71
|
+
[2 :age 25]
|
|
72
|
+
[1 :age 44]
|
|
73
|
+
[2 :name "Ivan"]
|
|
74
|
+
[1 :name "Petr"]
|
|
75
|
+
[3 :name "Sergey"]])))
|
|
76
|
+
|
|
77
|
+
(testing "Closest value lookup"
|
|
78
|
+
(is (= (map dvec (d/seek-datoms db :avet :name "P"))
|
|
79
|
+
[[1 :name "Petr"]
|
|
80
|
+
[3 :name "Sergey"]])))
|
|
81
|
+
|
|
82
|
+
(testing "Exact value lookup"
|
|
83
|
+
(is (= (map dvec (d/seek-datoms db :avet :name "Petr"))
|
|
84
|
+
[[1 :name "Petr"]
|
|
85
|
+
[3 :name "Sergey"]])))))
|
|
86
|
+
|
|
87
|
+
#_(deftest test-rseek-datoms ;; TODO: implement rseek within hitchhiker tree
|
|
88
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
89
|
+
db (-> (db/empty-db {:name {:db/index true}
|
|
90
|
+
:age {:db/index true}})
|
|
91
|
+
(d/db-with [[:db/add 1 :name "Petr"]
|
|
92
|
+
[:db/add 1 :age 44]
|
|
93
|
+
[:db/add 2 :name "Ivan"]
|
|
94
|
+
[:db/add 2 :age 25]
|
|
95
|
+
[:db/add 3 :name "Sergey"]
|
|
96
|
+
[:db/add 3 :age 11]]))]
|
|
97
|
+
|
|
98
|
+
(testing "Non-termination"
|
|
99
|
+
(is (= (map dvec (d/rseek-datoms db :avet :name "Petr"))
|
|
100
|
+
[[1 :name "Petr"]
|
|
101
|
+
[2 :name "Ivan"]
|
|
102
|
+
[1 :age 44]
|
|
103
|
+
[2 :age 25]
|
|
104
|
+
[3 :age 11]])))
|
|
105
|
+
|
|
106
|
+
(testing "Closest value lookup"
|
|
107
|
+
(is (= (map dvec (d/rseek-datoms db :avet :age 26))
|
|
108
|
+
[[2 :age 25]
|
|
109
|
+
[3 :age 11]])))
|
|
110
|
+
|
|
111
|
+
(testing "Exact value lookup"
|
|
112
|
+
(is (= (map dvec (d/rseek-datoms db :avet :age 25))
|
|
113
|
+
[[2 :age 25]
|
|
114
|
+
[3 :age 11]])))))
|
|
115
|
+
|
|
116
|
+
(deftest test-index-range
|
|
117
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
118
|
+
db (d/db-with
|
|
119
|
+
(db/empty-db {:name {:db/index true}
|
|
120
|
+
:age {:db/index true}})
|
|
121
|
+
[{:db/id 1 :name "Ivan" :age 15}
|
|
122
|
+
{:db/id 2 :name "Oleg" :age 20}
|
|
123
|
+
{:db/id 3 :name "Sergey" :age 7}
|
|
124
|
+
{:db/id 4 :name "Pavel" :age 45}
|
|
125
|
+
{:db/id 5 :name "Petr" :age 20}])]
|
|
126
|
+
(is (= (map dvec (d/index-range db {:attrid :name :start "Pe" :end "S"}))
|
|
127
|
+
[[5 :name "Petr"]]))
|
|
128
|
+
(is (= (map dvec (d/index-range db {:attrid :name :start "O" :end "Sergey"}))
|
|
129
|
+
[[2 :name "Oleg"]
|
|
130
|
+
[4 :name "Pavel"]
|
|
131
|
+
[5 :name "Petr"]
|
|
132
|
+
[3 :name "Sergey"]]))
|
|
133
|
+
|
|
134
|
+
(is (= (map dvec (d/index-range db {:attrid :name :start nil :end "P"}))
|
|
135
|
+
[[1 :name "Ivan"]
|
|
136
|
+
[2 :name "Oleg"]]))
|
|
137
|
+
(is (= (map dvec (d/index-range db {:attrid :name :start "R" :end nil}))
|
|
138
|
+
[[3 :name "Sergey"]]))
|
|
139
|
+
(is (= (map dvec (d/index-range db {:attrid :name :start nil :end nil}))
|
|
140
|
+
[[1 :name "Ivan"]
|
|
141
|
+
[2 :name "Oleg"]
|
|
142
|
+
[4 :name "Pavel"]
|
|
143
|
+
[5 :name "Petr"]
|
|
144
|
+
[3 :name "Sergey"]]))
|
|
145
|
+
|
|
146
|
+
(is (= (map dvec (d/index-range db {:attrid :age :start 15 :end 20}))
|
|
147
|
+
[[1 :age 15]
|
|
148
|
+
[2 :age 20]
|
|
149
|
+
[5 :age 20]]))
|
|
150
|
+
(is (= (map dvec (d/index-range db {:attrid :age :start 7 :end 45}))
|
|
151
|
+
[[3 :age 7]
|
|
152
|
+
[1 :age 15]
|
|
153
|
+
[2 :age 20]
|
|
154
|
+
[5 :age 20]
|
|
155
|
+
[4 :age 45]]))
|
|
156
|
+
(is (= (map dvec (d/index-range db {:attrid :age :start 0 :end 100}))
|
|
157
|
+
[[3 :age 7]
|
|
158
|
+
[1 :age 15]
|
|
159
|
+
[2 :age 20]
|
|
160
|
+
[5 :age 20]
|
|
161
|
+
[4 :age 45]]))))
|
|
162
|
+
|
|
163
|
+
(deftest test-slice []
|
|
164
|
+
(testing "Test index -slice"
|
|
165
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
166
|
+
db (d/db-with
|
|
167
|
+
(db/empty-db {:name {:db/index true}
|
|
168
|
+
:age {:db/index true}})
|
|
169
|
+
[{:db/id 1 :name "Ivan" :age 15}
|
|
170
|
+
{:db/id 2 :name "Oleg" :age 20}
|
|
171
|
+
{:db/id 3 :name "Sergey" :age 7}
|
|
172
|
+
{:db/id 4 :name "Pavel" :age 45}
|
|
173
|
+
{:db/id 5 :name "Petr" :age 20}])
|
|
174
|
+
eavt (:eavt db)
|
|
175
|
+
aevt (:aevt db)
|
|
176
|
+
avet (:avet db)]
|
|
177
|
+
|
|
178
|
+
(is (= (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom emax nil nil txmax) :eavt)
|
|
179
|
+
(d/datoms db :eavt)))
|
|
180
|
+
(is (= (map dvec (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom 2 nil nil txmax) :eavt))
|
|
181
|
+
[[1 :age 15]
|
|
182
|
+
[1 :name "Ivan"]
|
|
183
|
+
[2 :age 20]
|
|
184
|
+
[2 :name "Oleg"]]))
|
|
185
|
+
(is (= (map dvec (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom 3 :age 7 txmax) :eavt))
|
|
186
|
+
[[1 :age 15]
|
|
187
|
+
[1 :name "Ivan"]
|
|
188
|
+
[2 :age 20]
|
|
189
|
+
[2 :name "Oleg"]
|
|
190
|
+
[3 :age 7]]))
|
|
191
|
+
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 3 :name "Timofey" txmax) :eavt))
|
|
192
|
+
[[1 :age 15]
|
|
193
|
+
[1 :name "Ivan"]
|
|
194
|
+
[2 :age 20]
|
|
195
|
+
[2 :name "Oleg"]
|
|
196
|
+
[3 :age 7]
|
|
197
|
+
[3 :name "Sergey"]]))
|
|
198
|
+
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 3 :name "Timofey" tx0) :eavt))
|
|
199
|
+
[[1 :age 15]
|
|
200
|
+
[1 :name "Ivan"]
|
|
201
|
+
[2 :age 20]
|
|
202
|
+
[2 :name "Oleg"]
|
|
203
|
+
[3 :age 7]
|
|
204
|
+
[3 :name "Sergey"]]))
|
|
205
|
+
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 5 :age nil txmax) :eavt))
|
|
206
|
+
[[1 :age 15]
|
|
207
|
+
[1 :name "Ivan"]
|
|
208
|
+
[2 :age 20]
|
|
209
|
+
[2 :name "Oleg"]
|
|
210
|
+
[3 :age 7]
|
|
211
|
+
[3 :name "Sergey"]
|
|
212
|
+
[4 :age 45]
|
|
213
|
+
[4 :name "Pavel"]
|
|
214
|
+
[5 :age 20]]))
|
|
215
|
+
|
|
216
|
+
(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 3 :name "Pavel" txmax) :aevt))
|
|
217
|
+
[[1 :age 15]
|
|
218
|
+
[2 :age 20]
|
|
219
|
+
[3 :age 7]
|
|
220
|
+
[4 :age 45]
|
|
221
|
+
[5 :age 20]
|
|
222
|
+
[1 :name "Ivan"]
|
|
223
|
+
[2 :name "Oleg"]]))
|
|
224
|
+
(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 5 :age 18 txmax) :aevt))
|
|
225
|
+
[[1 :age 15]
|
|
226
|
+
[2 :age 20]
|
|
227
|
+
[3 :age 7]
|
|
228
|
+
[4 :age 45]]))
|
|
229
|
+
(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 3 :name nil txmax) :aevt))
|
|
230
|
+
[[1 :age 15]
|
|
231
|
+
[2 :age 20]
|
|
232
|
+
[3 :age 7]
|
|
233
|
+
[4 :age 45]
|
|
234
|
+
[5 :age 20]
|
|
235
|
+
[1 :name "Ivan"]
|
|
236
|
+
[2 :name "Oleg"]
|
|
237
|
+
[3 :name "Sergey"]]))
|
|
238
|
+
|
|
239
|
+
(is (= (map dvec (di/-slice avet (dd/datom e0 nil nil tx0) (dd/datom 3 :age 50 txmax) :avet))
|
|
240
|
+
[[3 :age 7]
|
|
241
|
+
[1 :age 15]
|
|
242
|
+
[2 :age 20]
|
|
243
|
+
[5 :age 20]
|
|
244
|
+
[4 :age 45]])))))
|
|
245
|
+
|
|
246
|
+
(deftest test-upsert-replace-comparators
|
|
247
|
+
(testing "Replace comparators return 0 for old/new datom pairs"
|
|
248
|
+
(let [old-datom (dd/datom 1 :name "Ivan" 100 true)
|
|
249
|
+
new-datom (dd/datom 1 :name "Petr" 101 true)]
|
|
250
|
+
|
|
251
|
+
(testing "EAVT replace comparator"
|
|
252
|
+
(let [cmp (dd/index-type->cmp-replace :eavt)]
|
|
253
|
+
(is (= 0 (cmp old-datom new-datom))
|
|
254
|
+
"EAVT replace should compare only (e,a), ignoring v and tx")))
|
|
255
|
+
|
|
256
|
+
(testing "AEVT replace comparator"
|
|
257
|
+
(let [cmp (dd/index-type->cmp-replace :aevt)]
|
|
258
|
+
(is (= 0 (cmp old-datom new-datom))
|
|
259
|
+
"AEVT replace should compare only (a,e), ignoring v and tx")))
|
|
260
|
+
|
|
261
|
+
(testing "AVET replace comparator"
|
|
262
|
+
(let [cmp (dd/index-type->cmp-replace :avet)]
|
|
263
|
+
(is (= 0 (cmp old-datom new-datom))
|
|
264
|
+
"AVET replace should compare only (a,e), ignoring v and tx - not (a,v)!")))))
|
|
265
|
+
|
|
266
|
+
(testing "Upsert operations work correctly when values change"
|
|
267
|
+
(let [old-datom (dd/datom 1 :age 25 100 true)
|
|
268
|
+
new-datom (dd/datom 1 :age 26 101 true)]
|
|
269
|
+
|
|
270
|
+
(testing "EAVT index upsert"
|
|
271
|
+
(let [index (psset/sorted-set* {:cmp (dd/index-type->cmp-quick :eavt)})
|
|
272
|
+
index-with-old (pset/insert index old-datom :eavt)
|
|
273
|
+
updated (pset/upsert index-with-old new-datom :eavt old-datom)
|
|
274
|
+
datoms (seq updated)]
|
|
275
|
+
(is (= 1 (count datoms))
|
|
276
|
+
"Should have exactly 1 datom after upsert")
|
|
277
|
+
(is (= new-datom (first datoms))
|
|
278
|
+
"Should contain the new datom, not the old one")))
|
|
279
|
+
|
|
280
|
+
(testing "AEVT index upsert"
|
|
281
|
+
(let [index (psset/sorted-set* {:cmp (dd/index-type->cmp-quick :aevt)})
|
|
282
|
+
index-with-old (pset/insert index old-datom :aevt)
|
|
283
|
+
updated (pset/upsert index-with-old new-datom :aevt old-datom)
|
|
284
|
+
datoms (seq updated)]
|
|
285
|
+
(is (= 1 (count datoms))
|
|
286
|
+
"Should have exactly 1 datom after upsert")
|
|
287
|
+
(is (= new-datom (first datoms))
|
|
288
|
+
"Should contain the new datom, not the old one")))
|
|
289
|
+
|
|
290
|
+
(testing "AVET index upsert"
|
|
291
|
+
(let [index (psset/sorted-set* {:cmp (dd/index-type->cmp-quick :avet)})
|
|
292
|
+
index-with-old (pset/insert index old-datom :avet)
|
|
293
|
+
updated (pset/upsert index-with-old new-datom :avet old-datom)
|
|
294
|
+
datoms (seq updated)]
|
|
295
|
+
(is (= 1 (count datoms))
|
|
296
|
+
"Should have exactly 1 datom after upsert")
|
|
297
|
+
(is (= new-datom (first datoms))
|
|
298
|
+
"Should contain the new datom, not the old one")))))
|
|
299
|
+
|
|
300
|
+
(testing "Upsert with different entity IDs does not use replace"
|
|
301
|
+
(let [datom1 (dd/datom 1 :age 25 100 true)
|
|
302
|
+
datom2 (dd/datom 2 :age 26 101 true)]
|
|
303
|
+
|
|
304
|
+
(testing "AVET index - different entities, same attribute"
|
|
305
|
+
(let [index (psset/sorted-set* {:cmp (dd/index-type->cmp-quick :avet)})
|
|
306
|
+
index-with-d1 (pset/insert index datom1 :avet)
|
|
307
|
+
updated (pset/upsert index-with-d1 datom2 :avet nil) ; nil old-datom means insert
|
|
308
|
+
datoms (seq updated)]
|
|
309
|
+
(is (= 2 (count datoms))
|
|
310
|
+
"Should have 2 datoms when upserting different entities")
|
|
311
|
+
(is (some #(= datom1 %) datoms)
|
|
312
|
+
"Should still contain the first datom")
|
|
313
|
+
(is (some #(= datom2 %) datoms)
|
|
314
|
+
"Should also contain the second datom"))))))
|
|
315
|
+
|
|
316
|
+
(deftest test-avet-upsert-replace-ordering-inconsistency
|
|
317
|
+
(testing "AVET upsert must handle case where (a,v,e) and (a,e) orderings differ"
|
|
318
|
+
(let [index (psset/sorted-set* {:cmp (dd/index-type->cmp-quick :avet)})
|
|
319
|
+
datom-e2-v50 (dd/datom 2 42 50 100 true)
|
|
320
|
+
datom-e3-v75 (dd/datom 3 42 75 100 true)
|
|
321
|
+
datom-e1-v100 (dd/datom 1 42 100 100 true)
|
|
322
|
+
index-with-three (-> index
|
|
323
|
+
(pset/insert datom-e2-v50 :avet)
|
|
324
|
+
(pset/insert datom-e3-v75 :avet)
|
|
325
|
+
(pset/insert datom-e1-v100 :avet))]
|
|
326
|
+
(is (= 3 (count (seq index-with-three)))
|
|
327
|
+
"Should have 3 datoms")
|
|
328
|
+
(is (some #(= datom-e1-v100 %) (seq index-with-three))
|
|
329
|
+
"Datom [e=1, a=42, v=100] should exist")
|
|
330
|
+
(is (some #(= datom-e2-v50 %) (seq index-with-three))
|
|
331
|
+
"Datom [e=2, a=42, v=50] should exist")
|
|
332
|
+
(is (some #(= datom-e3-v75 %) (seq index-with-three))
|
|
333
|
+
"Datom [e=3, a=42, v=75] should exist")
|
|
334
|
+
(let [new-datom-e1-v25 (dd/datom 1 42 25 101 true)
|
|
335
|
+
updated (pset/upsert index-with-three new-datom-e1-v25 :avet datom-e1-v100)]
|
|
336
|
+
(is (= 3 (count (seq updated)))
|
|
337
|
+
"Should still have 3 datoms after upsert")
|
|
338
|
+
(is (some #(= datom-e2-v50 %) (seq updated))
|
|
339
|
+
"Datom [e=2, a=42, v=50] should STILL exist after replacing [e=1, a=42, v=100]")
|
|
340
|
+
(is (some #(= datom-e3-v75 %) (seq updated))
|
|
341
|
+
"Datom [e=3, a=42, v=75] should STILL exist after replacing [e=1, a=42, v=100]")
|
|
342
|
+
(is (some #(= new-datom-e1-v25 %) (seq updated))
|
|
343
|
+
"Datom [e=1, a=42, v=25] should exist after replacement")
|
|
344
|
+
(is (not (some #(= datom-e1-v100 %) (seq updated)))
|
|
345
|
+
"Old datom [e=1, a=42, v=100] should NOT exist after replacement")))))
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
(ns datahike.test.insert
|
|
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
|
+
|
|
7
|
+
#?(:cljs
|
|
8
|
+
(def Throwable js/Error))
|
|
9
|
+
|
|
10
|
+
;; Test that the second insertion of the same datom does not replace the initial one.
|
|
11
|
+
;; That is similar to Datomic's behaviour.
|
|
12
|
+
|
|
13
|
+
(defn duplicate-test [config]
|
|
14
|
+
(when (d/database-exists? config)
|
|
15
|
+
(d/delete-database config))
|
|
16
|
+
(let [_ (d/create-database config)
|
|
17
|
+
conn (d/connect config)
|
|
18
|
+
schema [{:db/ident :block/string
|
|
19
|
+
:db/valueType :db.type/string
|
|
20
|
+
:db/cardinality :db.cardinality/one}
|
|
21
|
+
{:db/ident :block/children
|
|
22
|
+
:db/valueType :db.type/ref
|
|
23
|
+
:db/index true
|
|
24
|
+
:db/cardinality :db.cardinality/many}]
|
|
25
|
+
_ (d/transact conn schema)
|
|
26
|
+
_ (d/transact conn [{:db/id 501 :block/string "one"}])
|
|
27
|
+
_ (d/transact conn [{:db/id 502 :block/children 501}]) ;; First transacton
|
|
28
|
+
datom-1 (first (d/datoms @conn :eavt 502 :block/children))
|
|
29
|
+
_ (d/transact conn [{:db/id 502 :block/children 501}]) ;; Second transaction
|
|
30
|
+
datom-2 (first (d/datoms @conn :eavt 502 :block/children))
|
|
31
|
+
aevt (d/datoms @conn :aevt :block/children 502)
|
|
32
|
+
avet (d/datoms @conn :avet :block/children 501)]
|
|
33
|
+
(is (= (.-tx datom-1) (.-tx datom-2)))
|
|
34
|
+
(is (= datom-1 datom-2))
|
|
35
|
+
|
|
36
|
+
(is (= 1 (count aevt)))
|
|
37
|
+
(is (= datom-1 (first aevt)))
|
|
38
|
+
|
|
39
|
+
(is (= 1 (count avet)))
|
|
40
|
+
(is (= datom-1 (first avet)))
|
|
41
|
+
|
|
42
|
+
(d/release conn)
|
|
43
|
+
(d/delete-database config)))
|
|
44
|
+
|
|
45
|
+
(deftest duplicate-mem
|
|
46
|
+
(let [config {:store {:backend :memory :id #uuid "00140000-0000-0000-0000-000000000014"}
|
|
47
|
+
:schema-flexibility :write}]
|
|
48
|
+
(duplicate-test config)))
|
|
49
|
+
|
|
50
|
+
(deftest duplicate-file
|
|
51
|
+
(let [config {:store {:backend :file :path "/tmp/duplicate" :id #uuid "1a5e0000-0000-0000-0000-000000000001"}
|
|
52
|
+
:schema-flexibility :write}]
|
|
53
|
+
(duplicate-test config)))
|
|
54
|
+
|
|
55
|
+
(defn insert-history-test [cfg]
|
|
56
|
+
(let [schema [{:db/ident :name
|
|
57
|
+
:db/cardinality :db.cardinality/one
|
|
58
|
+
:db/index true
|
|
59
|
+
:db/unique :db.unique/identity
|
|
60
|
+
:db/valueType :db.type/string}
|
|
61
|
+
{:db/ident :email
|
|
62
|
+
:db/cardinality :db.cardinality/many
|
|
63
|
+
:db/valueType :db.type/string}]
|
|
64
|
+
_ (d/delete-database cfg)
|
|
65
|
+
_ (d/create-database cfg)
|
|
66
|
+
conn (d/connect cfg)]
|
|
67
|
+
(testing "inserting a new datom creates an entry in history"
|
|
68
|
+
(d/transact conn {:tx-data schema})
|
|
69
|
+
(d/transact conn {:tx-data [{:name "Alice"
|
|
70
|
+
:email "al@al.com"}]})
|
|
71
|
+
(is (= 1 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :email)))))
|
|
72
|
+
(testing "inserting the exact same datom does not change history"
|
|
73
|
+
(d/transact conn {:tx-data [{:db/id [:name "Alice"]
|
|
74
|
+
:email "al@al.com"}]})
|
|
75
|
+
(is (= 1 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :email)))))
|
|
76
|
+
(testing "changing the datom value just add the new datom to history"
|
|
77
|
+
(d/transact conn {:tx-data [{:db/id [:name "Alice"]
|
|
78
|
+
:email "al@eco.com"}]})
|
|
79
|
+
(is (= 2 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :email)))))
|
|
80
|
+
(d/release conn)))
|
|
81
|
+
|
|
82
|
+
(deftest insert-history-mem
|
|
83
|
+
(let [config {:store {:backend :memory :id #uuid "00150000-0000-0000-0000-000000000015"}
|
|
84
|
+
:schema-flexibility :write
|
|
85
|
+
:keep-history? true}]
|
|
86
|
+
(insert-history-test config)))
|
|
87
|
+
|
|
88
|
+
(deftest insert-history-file
|
|
89
|
+
(let [config {:store {:backend :file :path "/tmp/insert-hist-hht" :id #uuid "1a5e0000-0000-0000-0000-000000000002"}
|
|
90
|
+
:schema-flexibility :write
|
|
91
|
+
:keep-history? true}]
|
|
92
|
+
(insert-history-test config)))
|
|
93
|
+
|
|
94
|
+
(deftest insert-history-file-with-attr-refs
|
|
95
|
+
(let [config {:store {:backend :file :path "/tmp/insert-hist-attr-refs" :id #uuid "1a5e0000-0000-0000-0000-000000000003"}
|
|
96
|
+
:schema-flexibility :write
|
|
97
|
+
:keep-history? true
|
|
98
|
+
:attribute-refs? true}]
|
|
99
|
+
(insert-history-test config)))
|
|
100
|
+
|
|
101
|
+
(deftest insert-read-handlers
|
|
102
|
+
(let [config {:store {:backend :file :path "/tmp/insert-read-handlers-9" :id #uuid "1a5e0000-0000-0000-0000-000000000004"}
|
|
103
|
+
:schema-flexibility :write
|
|
104
|
+
:keep-history? false}
|
|
105
|
+
schema [{:db/ident :block/string
|
|
106
|
+
:db/valueType :db.type/string
|
|
107
|
+
:db/cardinality :db.cardinality/one}
|
|
108
|
+
{:db/ident :block/children
|
|
109
|
+
:db/valueType :db.type/ref
|
|
110
|
+
:db/index true
|
|
111
|
+
:db/cardinality :db.cardinality/many}]
|
|
112
|
+
_ (d/delete-database config)
|
|
113
|
+
_ (d/create-database config)
|
|
114
|
+
conn (d/connect config)]
|
|
115
|
+
(d/transact conn schema)
|
|
116
|
+
(d/transact conn (vec (for [i (range 1000)]
|
|
117
|
+
{:db/id (inc i) :block/children (inc i)})))
|
|
118
|
+
(d/release conn)
|
|
119
|
+
|
|
120
|
+
(let [conn (d/connect config)]
|
|
121
|
+
;; Would fail if insert read handlers are not present
|
|
122
|
+
(is (d/datoms @conn :eavt))
|
|
123
|
+
(d/release conn))
|
|
124
|
+
|
|
125
|
+
(d/delete-database config)))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
(ns datahike.test.listen-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is deftest]])
|
|
5
|
+
[datahike.api :as d]
|
|
6
|
+
[datahike.datom :as dd]
|
|
7
|
+
[datahike.constants :as const]
|
|
8
|
+
[datahike.test.utils :as du]
|
|
9
|
+
[datahike.test.core-test]))
|
|
10
|
+
|
|
11
|
+
(deftest test-listen!
|
|
12
|
+
(let [conn (du/setup-db)
|
|
13
|
+
reports (atom [])]
|
|
14
|
+
(d/transact conn {:tx-data [[:db/add -1 :name "Alex"]
|
|
15
|
+
[:db/add -2 :name "Boris"]]})
|
|
16
|
+
(d/listen conn :test #(swap! reports conj %))
|
|
17
|
+
(d/transact conn {:tx-data [[:db/add -1 :name "Dima"]
|
|
18
|
+
[:db/add -1 :age 19]
|
|
19
|
+
[:db/add -2 :name "Evgeny"]]
|
|
20
|
+
:tx-meta {:some-metadata 1}})
|
|
21
|
+
(d/transact conn {:tx-data [[:db/add -1 :name "Fedor"]
|
|
22
|
+
[:db/add 1 :name "Alex2"] ;; should update
|
|
23
|
+
[:db/retract 2 :name "Not Boris"] ;; should be skipped
|
|
24
|
+
[:db/retract 4 :name "Evgeny"]]})
|
|
25
|
+
(d/unlisten conn :test)
|
|
26
|
+
(d/transact conn {:tx-data [[:db/add -1 :name "Georgy"]]})
|
|
27
|
+
|
|
28
|
+
(is (= [(dd/datom (+ const/tx0 2) :some-metadata 1 (+ const/tx0 2) true)
|
|
29
|
+
(dd/datom 3 :name "Dima" (+ const/tx0 2) true)
|
|
30
|
+
(dd/datom 3 :age 19 (+ const/tx0 2) true)
|
|
31
|
+
(dd/datom 4 :name "Evgeny" (+ const/tx0 2) true)]
|
|
32
|
+
(rest (:tx-data (first @reports)))))
|
|
33
|
+
(is (= {:some-metadata 1}
|
|
34
|
+
(dissoc (:tx-meta (first @reports)) :db/txInstant :db/commitId)))
|
|
35
|
+
(is (= [(dd/datom 5 :name "Fedor" (+ const/tx0 3) true)
|
|
36
|
+
(dd/datom 1 :name "Alex2" (+ const/tx0 3) true)
|
|
37
|
+
(dd/datom 4 :name "Evgeny" (+ const/tx0 3) false)]
|
|
38
|
+
(rest (:tx-data (second @reports)))))
|
|
39
|
+
(is (= (dissoc (:tx-meta (second @reports)) :db/txInstant :db/commitId)
|
|
40
|
+
{}))
|
|
41
|
+
(d/release conn)))
|