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,291 @@
|
|
|
1
|
+
(ns datahike.test.unstructured-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.experimental.unstructured :as du]))
|
|
7
|
+
|
|
8
|
+
(deftest test-value-type-inference
|
|
9
|
+
(testing "Basic type inference"
|
|
10
|
+
(is (= :db.type/long (du/value->type 42)))
|
|
11
|
+
(is (= :db.type/float (du/value->type (float 42.0))))
|
|
12
|
+
(is (= :db.type/string (du/value->type "hello")))
|
|
13
|
+
(is (= :db.type/boolean (du/value->type true)))
|
|
14
|
+
(is (= :db.type/keyword (du/value->type :keyword)))
|
|
15
|
+
(is (= :db.type/ref (du/value->type {:a 1})))))
|
|
16
|
+
|
|
17
|
+
(deftest test-schema-inference
|
|
18
|
+
(testing "Schema inference for basic values"
|
|
19
|
+
(is (= {:db/ident :name
|
|
20
|
+
:db/valueType :db.type/string
|
|
21
|
+
:db/cardinality :db.cardinality/one}
|
|
22
|
+
(du/infer-value-schema :name "Alice"))))
|
|
23
|
+
|
|
24
|
+
(testing "Schema inference for collections"
|
|
25
|
+
(is (= {:db/ident :tags
|
|
26
|
+
:db/valueType :db.type/keyword
|
|
27
|
+
:db/cardinality :db.cardinality/many}
|
|
28
|
+
(du/infer-value-schema :tags [:tag1 :tag2])))
|
|
29
|
+
|
|
30
|
+
(is (= {:db/ident :address
|
|
31
|
+
:db/valueType :db.type/ref
|
|
32
|
+
:db/cardinality :db.cardinality/one}
|
|
33
|
+
(du/infer-value-schema :address {:street "123 Main St"}))))
|
|
34
|
+
|
|
35
|
+
(testing "Empty vector handling"
|
|
36
|
+
(is (nil? (du/infer-value-schema :empty-tags [])))))
|
|
37
|
+
|
|
38
|
+
(deftest test-process-unstructured-data
|
|
39
|
+
(testing "Processing simple data"
|
|
40
|
+
(let [data {:name "Alice" :age 30}
|
|
41
|
+
result (du/process-unstructured-data data)]
|
|
42
|
+
(is (= 2 (count (:schema result))))
|
|
43
|
+
(is (= 1 (count (:tx-data result))))
|
|
44
|
+
(is (= -1 (:db/id (first (:tx-data result)))))))
|
|
45
|
+
|
|
46
|
+
(testing "Processing nested data"
|
|
47
|
+
(let [data {:name "Bob"
|
|
48
|
+
:age 25
|
|
49
|
+
:address {:street "123 Main St"
|
|
50
|
+
:city "Anytown"}}
|
|
51
|
+
result (du/process-unstructured-data data)]
|
|
52
|
+
;; There should be 5 schema entries: name, age, address, street, city
|
|
53
|
+
(is (= 5 (count (:schema result))))
|
|
54
|
+
(is (= 2 (count (:tx-data result))))
|
|
55
|
+
(is (some #(= -1 (:db/id %)) (:tx-data result)))))
|
|
56
|
+
|
|
57
|
+
(testing "Processing empty vectors"
|
|
58
|
+
(let [data {:name "Charlie"
|
|
59
|
+
:tags []}
|
|
60
|
+
result (du/process-unstructured-data data)]
|
|
61
|
+
;; The schema should only include the name attribute, not tags
|
|
62
|
+
(is (= 1 (count (:schema result))))
|
|
63
|
+
(is (= :name
|
|
64
|
+
(-> result :schema first :db/ident)))
|
|
65
|
+
;; The transaction data should still include the empty tags vector
|
|
66
|
+
(let [tx-entity (first (:tx-data result))]
|
|
67
|
+
(is (= "Charlie" (:name tx-entity)))
|
|
68
|
+
(is (= [] (:tags tx-entity)))))))
|
|
69
|
+
|
|
70
|
+
(deftest test-basic-schema-on-read
|
|
71
|
+
(testing "Basic operations with schema-on-read"
|
|
72
|
+
(let [cfg {:store {:backend :memory
|
|
73
|
+
:id #uuid "10000000-0000-0000-0000-000000000001"}
|
|
74
|
+
:schema-flexibility :read}
|
|
75
|
+
_ (d/delete-database cfg)
|
|
76
|
+
_ (d/create-database cfg)
|
|
77
|
+
conn (d/connect cfg)]
|
|
78
|
+
|
|
79
|
+
;; Just add simple data directly
|
|
80
|
+
(d/transact conn [{:name "Alice" :age 30}])
|
|
81
|
+
|
|
82
|
+
;; Simple query
|
|
83
|
+
(is (= #{["Alice"]}
|
|
84
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/db conn))))
|
|
85
|
+
|
|
86
|
+
(d/release conn))))
|
|
87
|
+
|
|
88
|
+
(deftest test-unstructured-schema-on-read
|
|
89
|
+
(testing "Using process-unstructured-data with schema-on-read"
|
|
90
|
+
(let [cfg {:store {:backend :memory
|
|
91
|
+
:id #uuid "20000000-0000-0000-0000-000000000002"}
|
|
92
|
+
:schema-flexibility :read}
|
|
93
|
+
_ (d/delete-database cfg)
|
|
94
|
+
_ (d/create-database cfg)
|
|
95
|
+
conn (d/connect cfg)
|
|
96
|
+
data {:name "Bob"
|
|
97
|
+
:age 25
|
|
98
|
+
:address {:street "123 Main St"
|
|
99
|
+
:city "Anytown"}}]
|
|
100
|
+
|
|
101
|
+
;; Use process-unstructured-data to prepare data
|
|
102
|
+
(let [processed (du/process-unstructured-data data)
|
|
103
|
+
tx-report (d/transact conn (:tx-data processed))]
|
|
104
|
+
|
|
105
|
+
;; Verify simple attribute
|
|
106
|
+
(is (= #{["Bob"]}
|
|
107
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/db conn))))
|
|
108
|
+
|
|
109
|
+
;; We can't directly query nested data with the temp IDs in the schema-on-read mode
|
|
110
|
+
;; This requires a different approach
|
|
111
|
+
;; Let's verify we can at least retrieve the address entity id
|
|
112
|
+
(let [address-id (d/q '[:find ?a :where [?e :address ?a]] (d/db conn))]
|
|
113
|
+
(is (not (empty? address-id)))))
|
|
114
|
+
|
|
115
|
+
(d/release conn))))
|
|
116
|
+
|
|
117
|
+
(deftest test-transact-unstructured-api
|
|
118
|
+
(testing "Using the transact-unstructured API with schema-on-read"
|
|
119
|
+
(let [cfg {:store {:backend :memory
|
|
120
|
+
:id #uuid "30000000-0000-0000-0000-000000000003"}
|
|
121
|
+
:schema-flexibility :read}
|
|
122
|
+
_ (d/delete-database cfg)
|
|
123
|
+
_ (d/create-database cfg)
|
|
124
|
+
conn (d/connect cfg)
|
|
125
|
+
data {:name "Charlie"
|
|
126
|
+
:age 35
|
|
127
|
+
:skills ["programming" "design" "management"]
|
|
128
|
+
:contact {:email "charlie@example.com"
|
|
129
|
+
:phone "555-1234"}}]
|
|
130
|
+
|
|
131
|
+
;; Use the high-level API
|
|
132
|
+
(du/transact-unstructured conn data)
|
|
133
|
+
|
|
134
|
+
;; Verify basic data
|
|
135
|
+
(is (= #{["Charlie"]}
|
|
136
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/db conn))))
|
|
137
|
+
(is (= #{[35]}
|
|
138
|
+
(d/q '[:find ?a :where [?e :age ?a]] (d/db conn))))
|
|
139
|
+
|
|
140
|
+
;; Verify array data - just check if any skills were added
|
|
141
|
+
(let [skills (d/q '[:find ?s :where [_ :skills ?s]] (d/db conn))]
|
|
142
|
+
(is (not (empty? skills))))
|
|
143
|
+
|
|
144
|
+
;; Verify that nested object was stored properly by checking contact
|
|
145
|
+
(let [contacts (d/q '[:find ?e :where [?e :email "charlie@example.com"]] (d/db conn))]
|
|
146
|
+
(is (not (empty? contacts))))
|
|
147
|
+
|
|
148
|
+
(d/release conn))))
|
|
149
|
+
|
|
150
|
+
(deftest test-schema-on-write
|
|
151
|
+
(testing "Using transact-unstructured with schema-on-write"
|
|
152
|
+
(let [cfg {:store {:backend :memory
|
|
153
|
+
:id #uuid "40000000-0000-0000-0000-000000000004"}} ;; Default is schema-on-write
|
|
154
|
+
_ (d/delete-database cfg)
|
|
155
|
+
_ (d/create-database cfg)
|
|
156
|
+
conn (d/connect cfg)
|
|
157
|
+
data {:name "Diana"
|
|
158
|
+
:age 28
|
|
159
|
+
:active true}]
|
|
160
|
+
|
|
161
|
+
;; First, verify that we can't insert data directly (requires schema)
|
|
162
|
+
(is (thrown? Exception
|
|
163
|
+
(d/transact conn [data])))
|
|
164
|
+
|
|
165
|
+
;; Now use transact-unstructured, which should infer and apply schema first
|
|
166
|
+
(du/transact-unstructured conn data)
|
|
167
|
+
|
|
168
|
+
;; Verify the schema was created
|
|
169
|
+
(let [schema-query '[:find ?a ?t ?c
|
|
170
|
+
:where
|
|
171
|
+
[?e :db/ident ?a]
|
|
172
|
+
[?e :db/valueType ?t]
|
|
173
|
+
[?e :db/cardinality ?c]]]
|
|
174
|
+
(is (= #{[:name :db.type/string :db.cardinality/one]
|
|
175
|
+
[:age :db.type/long :db.cardinality/one]
|
|
176
|
+
[:active :db.type/boolean :db.cardinality/one]}
|
|
177
|
+
(d/q schema-query (d/db conn)))))
|
|
178
|
+
|
|
179
|
+
;; Verify the data was inserted
|
|
180
|
+
(is (= #{["Diana"]}
|
|
181
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/db conn))))
|
|
182
|
+
(is (= #{[28]}
|
|
183
|
+
(d/q '[:find ?a :where [?e :age ?a]] (d/db conn))))
|
|
184
|
+
(is (= #{[true]}
|
|
185
|
+
(d/q '[:find ?a :where [?e :active ?a]] (d/db conn))))
|
|
186
|
+
|
|
187
|
+
;; Test schema evolution with new attributes
|
|
188
|
+
(let [new-data {:name "Erik"
|
|
189
|
+
:age 42
|
|
190
|
+
:email "erik@example.com" ;; New attribute
|
|
191
|
+
:active false}]
|
|
192
|
+
|
|
193
|
+
;; This should work and auto-add the email schema
|
|
194
|
+
(du/transact-unstructured conn new-data)
|
|
195
|
+
|
|
196
|
+
;; Verify new schema was added
|
|
197
|
+
(let [schema-query '[:find ?a ?t ?c
|
|
198
|
+
:where
|
|
199
|
+
[?e :db/ident ?a]
|
|
200
|
+
[?e :db/valueType ?t]
|
|
201
|
+
[?e :db/cardinality ?c]]]
|
|
202
|
+
(is (= #{[:name :db.type/string :db.cardinality/one]
|
|
203
|
+
[:age :db.type/long :db.cardinality/one]
|
|
204
|
+
[:active :db.type/boolean :db.cardinality/one]
|
|
205
|
+
[:email :db.type/string :db.cardinality/one]}
|
|
206
|
+
(d/q schema-query (d/db conn)))))
|
|
207
|
+
|
|
208
|
+
;; Verify both records exist
|
|
209
|
+
(is (= #{["Diana"] ["Erik"]}
|
|
210
|
+
(d/q '[:find ?n :where [?e :name ?n]] (d/db conn))))
|
|
211
|
+
(is (= #{["erik@example.com"]}
|
|
212
|
+
(d/q '[:find ?e :where [_ :email ?e]] (d/db conn)))))
|
|
213
|
+
|
|
214
|
+
(d/release conn))))
|
|
215
|
+
|
|
216
|
+
(deftest test-cardinality-many-inference
|
|
217
|
+
(testing "Inferring cardinality/many from vector values"
|
|
218
|
+
(let [cfg {:store {:backend :memory
|
|
219
|
+
:id #uuid "50000000-0000-0000-0000-000000000005"}}
|
|
220
|
+
_ (d/delete-database cfg)
|
|
221
|
+
_ (d/create-database cfg)
|
|
222
|
+
conn (d/connect cfg)
|
|
223
|
+
;; First set up the schema for name with unique identity
|
|
224
|
+
_ (d/transact conn [{:db/ident :name
|
|
225
|
+
:db/valueType :db.type/string
|
|
226
|
+
:db/cardinality :db.cardinality/one
|
|
227
|
+
:db/unique :db.unique/identity}])
|
|
228
|
+
|
|
229
|
+
data {:name "Fiona"
|
|
230
|
+
:tags ["clojure" "datalog" "databases"]} ;; Vector = cardinality many
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
;; This should automatically set up the tags attribute as cardinality/many
|
|
234
|
+
(du/transact-unstructured conn data)
|
|
235
|
+
|
|
236
|
+
;; Verify the schema for tags with cardinality/many
|
|
237
|
+
(let [schema-query '[:find ?t ?c
|
|
238
|
+
:where
|
|
239
|
+
[?e :db/ident :tags]
|
|
240
|
+
[?e :db/valueType ?t]
|
|
241
|
+
[?e :db/cardinality ?c]]]
|
|
242
|
+
(is (= #{[:db.type/string :db.cardinality/many]} ;; Check cardinality/many
|
|
243
|
+
(d/q schema-query (d/db conn)))))
|
|
244
|
+
|
|
245
|
+
;; Verify all array values were stored
|
|
246
|
+
(let [tags (d/q '[:find ?t :where [_ :tags ?t]] (d/db conn))]
|
|
247
|
+
(is (= #{"clojure" "datalog" "databases"}
|
|
248
|
+
(set (map first tags)))))
|
|
249
|
+
|
|
250
|
+
;; Test adding more values to the array for the same entity
|
|
251
|
+
(d/transact conn [{:db/id [:name "Fiona"]
|
|
252
|
+
:tags ["datahike"]}]) ;; Add another tag
|
|
253
|
+
|
|
254
|
+
;; Verify all tags are preserved (cardinality/many behavior)
|
|
255
|
+
(let [tags (d/q '[:find ?t :where [_ :tags ?t]] (d/db conn))]
|
|
256
|
+
(is (= #{"clojure" "datalog" "databases" "datahike"}
|
|
257
|
+
(set (map first tags)))))
|
|
258
|
+
|
|
259
|
+
(d/release conn))))
|
|
260
|
+
|
|
261
|
+
(deftest test-schema-conflict
|
|
262
|
+
(testing "Detecting schema conflicts"
|
|
263
|
+
(let [cfg {:store {:backend :memory
|
|
264
|
+
:id #uuid "60000000-0000-0000-0000-000000000006"}}
|
|
265
|
+
_ (d/delete-database cfg)
|
|
266
|
+
_ (d/create-database cfg)
|
|
267
|
+
conn (d/connect cfg)]
|
|
268
|
+
|
|
269
|
+
;; First add schema for 'score' as a long
|
|
270
|
+
(d/transact conn [{:db/ident :score
|
|
271
|
+
:db/valueType :db.type/long
|
|
272
|
+
:db/cardinality :db.cardinality/one}])
|
|
273
|
+
|
|
274
|
+
;; Add a data point with correct type
|
|
275
|
+
(d/transact conn [{:score 100}])
|
|
276
|
+
|
|
277
|
+
;; Now try to add data with incompatible type (string instead of long)
|
|
278
|
+
(let [data {:name "Grace"
|
|
279
|
+
:score "High"}] ;; Score is a string but schema says long
|
|
280
|
+
|
|
281
|
+
;; This should detect the conflict and throw an exception
|
|
282
|
+
(is (thrown-with-msg? Exception #"Schema conflict detected"
|
|
283
|
+
(du/transact-unstructured conn data))))
|
|
284
|
+
|
|
285
|
+
;; Verify the data was not inserted
|
|
286
|
+
(is (empty? (d/q '[:find ?n :where [_ :name ?n]] (d/db conn))))
|
|
287
|
+
|
|
288
|
+
;; Verify the original score still works
|
|
289
|
+
(is (= #{[100]} (d/q '[:find ?s :where [_ :score ?s]] (d/db conn))))
|
|
290
|
+
|
|
291
|
+
(d/release conn))))
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
(ns datahike.test.upsert-impl-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
|
+
[hitchhiker.tree.utils.async :as ha]
|
|
6
|
+
[hitchhiker.tree :as tree]
|
|
7
|
+
[hitchhiker.tree.messaging :as msg]
|
|
8
|
+
[datahike.index.hitchhiker-tree.upsert :as htu]
|
|
9
|
+
[datahike.test.utils :refer [setup-db conn-id]]
|
|
10
|
+
[datahike.constants :as const]
|
|
11
|
+
[datahike.db :as db]
|
|
12
|
+
[datahike.api :as d]))
|
|
13
|
+
|
|
14
|
+
(defn upsert-helper
|
|
15
|
+
[t k]
|
|
16
|
+
(ha/<?? (msg/enqueue t [(htu/new-UpsertOp k 0 [0 1])])))
|
|
17
|
+
|
|
18
|
+
(deftest hh-tree-upsert
|
|
19
|
+
(let [new-tree (tree/b-tree (tree/->Config 3 3 2))
|
|
20
|
+
projected-vec [4 :name "Marcel" 1]
|
|
21
|
+
tree (reduce upsert-helper (ha/<?? new-tree)
|
|
22
|
+
(into (sorted-set)
|
|
23
|
+
#{[1 :at "home" 1]
|
|
24
|
+
[1 :age 44 1]
|
|
25
|
+
[1 :name "Petr" 1]
|
|
26
|
+
[2 :age 25 1]
|
|
27
|
+
[2 :name "Ivan" 1]
|
|
28
|
+
[3 :age 11 1]
|
|
29
|
+
projected-vec}))]
|
|
30
|
+
(testing "Against an entry in the projection area,"
|
|
31
|
+
(testing "we are in a projection"
|
|
32
|
+
(is (= (:key (first (:op-buf tree))) projected-vec)))
|
|
33
|
+
(testing "basic lookup works"
|
|
34
|
+
(is (= [[1 :age 44 1] nil] (first (msg/lookup-fwd-iter tree [1 :age 44 1])))))
|
|
35
|
+
(testing "a totally new entry is persisted"
|
|
36
|
+
(let [new [5 :name "Jo" 3]
|
|
37
|
+
tree-after (upsert-helper tree new)]
|
|
38
|
+
;; Is new in?
|
|
39
|
+
(is (= [new nil] (first (msg/lookup-fwd-iter tree-after new))))))
|
|
40
|
+
(testing "new = old"
|
|
41
|
+
(let [new [4 :name "Marcel" 2]
|
|
42
|
+
tree-after (upsert-helper tree new)]
|
|
43
|
+
(is (= [new nil] (first (msg/lookup-fwd-iter tree-after new))))))
|
|
44
|
+
(testing "old v <> new v,"
|
|
45
|
+
(testing "not keeping history"
|
|
46
|
+
(let [new [4 :name "New-Name" 2]
|
|
47
|
+
tree-after (upsert-helper tree new)]
|
|
48
|
+
;; Is new in?
|
|
49
|
+
(is (= [new nil] (first (msg/lookup-fwd-iter tree-after new))))
|
|
50
|
+
;; Is old deleted?
|
|
51
|
+
(is (= nil (msg/lookup tree-after projected-vec)))))))
|
|
52
|
+
|
|
53
|
+
(testing "Against an entry located at leaf level,"
|
|
54
|
+
(testing "basic lookup works"
|
|
55
|
+
(is (= [[1 :age 44 1] nil] (first (msg/lookup-fwd-iter tree [1 :age 44 1])))))
|
|
56
|
+
(testing "re-inserting works"
|
|
57
|
+
(let [new [1 :age 44 1]
|
|
58
|
+
tree-after (upsert-helper tree new)]
|
|
59
|
+
(is (= [new nil] (first (msg/lookup-fwd-iter tree-after new))))))
|
|
60
|
+
(testing "old v <> new v"
|
|
61
|
+
(testing "not keeping history"
|
|
62
|
+
(let [new [1 :age 40 5]
|
|
63
|
+
tree-after (upsert-helper tree new)]
|
|
64
|
+
;; Is new in?
|
|
65
|
+
(is (= [new nil] (first (msg/lookup-fwd-iter tree-after new))))
|
|
66
|
+
;; Is old deleted?
|
|
67
|
+
(is (= nil (msg/lookup tree-after [1 :age 44 1]))))))))
|
|
68
|
+
|
|
69
|
+
(testing "when it overflows"
|
|
70
|
+
;; I.e. testing the projection of a deferred-op sitting on an index-node.
|
|
71
|
+
(let [new-tree (tree/b-tree (tree/->Config 3 3 2))
|
|
72
|
+
tree (reduce upsert-helper (ha/<?? new-tree)
|
|
73
|
+
(into (sorted-set)
|
|
74
|
+
#{[1 :age 44 1]
|
|
75
|
+
[1 :name "Petr" 1]
|
|
76
|
+
[2 :age 25 1]
|
|
77
|
+
[2 :name "Ivan" 1]
|
|
78
|
+
[3 :age 11 1]
|
|
79
|
+
[4 :age 12 1]
|
|
80
|
+
[4 :age 20 1]
|
|
81
|
+
[4 :name "Paulo" 1]
|
|
82
|
+
[4 :age 40 1]}))] ;; triggers the overflow
|
|
83
|
+
|
|
84
|
+
(is (= nil (msg/lookup tree [4 :age 12 1])))
|
|
85
|
+
(is (= nil (msg/lookup tree [4 :age 20 1])))
|
|
86
|
+
(is (= [[1 :age 44 1] nil] (first (msg/lookup-fwd-iter tree [1 :age 44 1])))))))
|
|
87
|
+
|
|
88
|
+
(defn connect []
|
|
89
|
+
(let [cfg {:schema-flexibility :read
|
|
90
|
+
:store {:backend :memory :id (random-uuid)}
|
|
91
|
+
:initial-tx []}
|
|
92
|
+
_ (d/delete-database cfg)
|
|
93
|
+
_ (d/create-database cfg)]
|
|
94
|
+
(d/connect cfg)))
|
|
95
|
+
|
|
96
|
+
(deftest datahike-upsert
|
|
97
|
+
(testing "IndexNode"
|
|
98
|
+
(let [txs (vec (for [i (range 1000)]
|
|
99
|
+
{:name (str "Peter" i)
|
|
100
|
+
:age i}))
|
|
101
|
+
conn (connect)]
|
|
102
|
+
(is (d/transact conn txs))
|
|
103
|
+
(d/release conn)))
|
|
104
|
+
|
|
105
|
+
(testing "simple upsert and history"
|
|
106
|
+
(let [txs [[:db/add 199 :name "Peter"]
|
|
107
|
+
[:db/add 199 :name "Ptr"]]
|
|
108
|
+
conn (connect)]
|
|
109
|
+
(is (d/transact conn txs))
|
|
110
|
+
(is (not (d/datoms @conn :eavt 199 :name "Peter"))) ;; no history
|
|
111
|
+
(is (d/datoms (d/history @conn) :eavt 199 :name "Peter"))
|
|
112
|
+
(d/release conn)))
|
|
113
|
+
|
|
114
|
+
(testing "transacting the same datoms twice should work with :avet"
|
|
115
|
+
(let [dvec #(vector (:e %) (:a %) (:v %))
|
|
116
|
+
txs [[:db/add 1 :age 44]
|
|
117
|
+
[:db/add 2 :age 25]
|
|
118
|
+
[:db/add 3 :age 11]]
|
|
119
|
+
db (-> (db/empty-db {:age {:db/index true}})
|
|
120
|
+
(d/db-with txs)
|
|
121
|
+
;; transacting again
|
|
122
|
+
(d/db-with txs))]
|
|
123
|
+
(is (= [[3 :age 11]
|
|
124
|
+
[2 :age 25]
|
|
125
|
+
[1 :age 44]]
|
|
126
|
+
(map dvec (d/datoms db :avet)))))))
|
|
127
|
+
|
|
128
|
+
(deftest temporal-upsert
|
|
129
|
+
(let [schema [{:db/ident :name
|
|
130
|
+
:db/valueType :db.type/string
|
|
131
|
+
:db/unique :db.unique/identity
|
|
132
|
+
:db/index true
|
|
133
|
+
:db/cardinality :db.cardinality/one}
|
|
134
|
+
{:db/ident :age
|
|
135
|
+
:db/valueType :db.type/long
|
|
136
|
+
:db/cardinality :db.cardinality/one}]
|
|
137
|
+
initial-tx (conj schema
|
|
138
|
+
{:name "Alice"
|
|
139
|
+
:age 25}
|
|
140
|
+
{:name "Bob"
|
|
141
|
+
:age 35})
|
|
142
|
+
cfg {:store {:backend :memory
|
|
143
|
+
:id #uuid "70000000-0000-0000-0000-000000000007"}
|
|
144
|
+
:schema-flexibility :read
|
|
145
|
+
:initial-tx initial-tx}
|
|
146
|
+
conn (setup-db cfg)
|
|
147
|
+
query '[:find ?a ?t ?op
|
|
148
|
+
:where
|
|
149
|
+
[?e :name "Alice"]
|
|
150
|
+
[?e :age ?a ?t ?op]]]
|
|
151
|
+
(testing "when multiple transactions"
|
|
152
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 20]
|
|
153
|
+
[:db/add [:name "Bob"] :age 15]])
|
|
154
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 10]])
|
|
155
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 1]])
|
|
156
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
157
|
+
[25 (+ const/tx0 2) false]
|
|
158
|
+
[20 (+ const/tx0 2) true]
|
|
159
|
+
[20 (+ const/tx0 3) false]
|
|
160
|
+
[10 (+ const/tx0 3) true]
|
|
161
|
+
[10 (+ const/tx0 4) false]
|
|
162
|
+
[1 (+ const/tx0 4) true]}
|
|
163
|
+
(d/q query (d/history @conn))))
|
|
164
|
+
(d/release conn))
|
|
165
|
+
(testing "when only one transaction"
|
|
166
|
+
(let [conn (setup-db cfg)]
|
|
167
|
+
(d/transact conn [[:db/add [:name "Alice"] :age 20]
|
|
168
|
+
[:db/add [:name "Bob"] :age 15]
|
|
169
|
+
[:db/add [:name "Alice"] :age 10]
|
|
170
|
+
[:db/add [:name "Alice"] :age 1]])
|
|
171
|
+
(is (= #{[25 (+ const/tx0 1) true]
|
|
172
|
+
[25 (+ const/tx0 2) false]
|
|
173
|
+
[20 (+ const/tx0 2) true]
|
|
174
|
+
[20 (+ const/tx0 2) false]
|
|
175
|
+
[10 (+ const/tx0 2) true]
|
|
176
|
+
[10 (+ const/tx0 2) false]
|
|
177
|
+
[1 (+ const/tx0 2) true]}
|
|
178
|
+
(d/q query (d/history @conn))))
|
|
179
|
+
(d/release conn)))))
|
|
180
|
+
|
|
181
|
+
(deftest upsert-read-handlers
|
|
182
|
+
(let [config {:store {:backend :file :path "/tmp/upsert-read-handlers" :id #uuid "ab1d0000-0000-0000-0000-000000000001"}
|
|
183
|
+
:schema-flexibility :write
|
|
184
|
+
:keep-history? false}
|
|
185
|
+
schema [{:db/ident :block/string
|
|
186
|
+
:db/valueType :db.type/string
|
|
187
|
+
:db/cardinality :db.cardinality/one}
|
|
188
|
+
{:db/ident :block/children
|
|
189
|
+
:db/valueType :db.type/ref
|
|
190
|
+
:db/index true
|
|
191
|
+
:db/cardinality :db.cardinality/one}]
|
|
192
|
+
_ (d/delete-database config)
|
|
193
|
+
_ (d/create-database config)
|
|
194
|
+
conn (d/connect config)]
|
|
195
|
+
(d/transact conn schema)
|
|
196
|
+
(d/transact conn (vec (for [i (range 1000)]
|
|
197
|
+
{:db/id (inc i) :block/children (inc i)})))
|
|
198
|
+
(d/release conn)
|
|
199
|
+
|
|
200
|
+
(let [conn (d/connect config)]
|
|
201
|
+
;; Would fail if upsert read handlers are not present
|
|
202
|
+
(is (d/datoms @conn :eavt))
|
|
203
|
+
(d/release conn))
|
|
204
|
+
|
|
205
|
+
(d/delete-database config)))
|