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,956 @@
|
|
|
1
|
+
(ns ^:no-doc datahike.db
|
|
2
|
+
(:refer-clojure :exclude [seqable?])
|
|
3
|
+
(:require
|
|
4
|
+
[clojure.data :as data]
|
|
5
|
+
[clojure.walk :refer [postwalk]]
|
|
6
|
+
#?(:clj [clojure.pprint :as pp])
|
|
7
|
+
[datahike.config :as dc]
|
|
8
|
+
[datahike.constants :as c :refer [ue0 e0 tx0 utx0 emax txmax system-schema]]
|
|
9
|
+
[datahike.datom :as dd :refer [datom datom-tx datom-added]]
|
|
10
|
+
[datahike.db.interface :as dbi]
|
|
11
|
+
[datahike.db.search :as dbs]
|
|
12
|
+
[datahike.db.utils :as dbu]
|
|
13
|
+
[datahike.index :as di]
|
|
14
|
+
[datahike.schema :as ds]
|
|
15
|
+
[datahike.store :as store]
|
|
16
|
+
[datahike.tools :as tools :refer [raise group-by-step #?(:clj meta-data)]]
|
|
17
|
+
[org.replikativ.persistent-sorted-set.arrays :as arrays]
|
|
18
|
+
[medley.core :as m]
|
|
19
|
+
[taoensso.timbre :refer [warn]])
|
|
20
|
+
#?(:cljs (:require-macros [datahike.db :refer [defrecord-updatable]]
|
|
21
|
+
[datahike.datom :refer [combine-cmp datom]]
|
|
22
|
+
[datahike.tools :refer [raise meta-data]]))
|
|
23
|
+
#?(:clj (:import [clojure.lang AMapEntry ITransientCollection IEditableCollection IPersistentCollection Seqable
|
|
24
|
+
IHashEq Associative IKeywordLookup ILookup]
|
|
25
|
+
[datahike.datom Datom]
|
|
26
|
+
[java.io Writer]
|
|
27
|
+
[java.util Date])))
|
|
28
|
+
|
|
29
|
+
(declare equiv-db empty-db)
|
|
30
|
+
#?(:cljs (declare pr-db))
|
|
31
|
+
|
|
32
|
+
;; ----------------------------------------------------------------------------
|
|
33
|
+
;; macros and funcs to support writing defrecords and updating
|
|
34
|
+
;; (replacing) builtins, i.e., Object/hashCode, IHashEq hasheq, etc.
|
|
35
|
+
;; code taken from prismatic:
|
|
36
|
+
;; https://github.com/Prismatic/schema/commit/e31c419c56555c83ef9ee834801e13ef3c112597
|
|
37
|
+
;;
|
|
38
|
+
|
|
39
|
+
;; ----------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
#?(:cljs
|
|
42
|
+
(do
|
|
43
|
+
(def Exception js/Error)
|
|
44
|
+
(def IllegalArgumentException js/Error)
|
|
45
|
+
(def UnsupportedOperationException js/Error)))
|
|
46
|
+
|
|
47
|
+
;; ----------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
(defn #?@(:clj [^Boolean seqable?]
|
|
50
|
+
:cljs [^boolean seqable?])
|
|
51
|
+
[x]
|
|
52
|
+
(and (not (string? x))
|
|
53
|
+
#?(:cljs (or (cljs.core/seqable? x)
|
|
54
|
+
(arrays/array? x))
|
|
55
|
+
:clj (or (seq? x)
|
|
56
|
+
(instance? Seqable x)
|
|
57
|
+
(nil? x)
|
|
58
|
+
(instance? Iterable x)
|
|
59
|
+
(arrays/array? x)
|
|
60
|
+
(instance? java.util.Map x)))))
|
|
61
|
+
|
|
62
|
+
(defn- cljs-env?
|
|
63
|
+
"Take the &env from a macro, and tell whether we are expanding into cljs."
|
|
64
|
+
[env]
|
|
65
|
+
(boolean (:ns env)))
|
|
66
|
+
|
|
67
|
+
#?(:clj
|
|
68
|
+
(defmacro if-cljs
|
|
69
|
+
"Return then if we are generating cljs code and else for Clojure code.
|
|
70
|
+
https://groups.google.com/d/msg/clojurescript/iBY5HaQda4A/w1lAQi9_AwsJ"
|
|
71
|
+
[then else]
|
|
72
|
+
(if (cljs-env? &env) then else)))
|
|
73
|
+
|
|
74
|
+
#?(:clj
|
|
75
|
+
(defn- get-sig [method]
|
|
76
|
+
;; expects something like '(method-symbol [arg arg arg] ...)
|
|
77
|
+
;; if the thing matches, returns [fully-qualified-symbol arity], otherwise nil
|
|
78
|
+
(and (sequential? method)
|
|
79
|
+
(symbol? (first method))
|
|
80
|
+
(vector? (second method))
|
|
81
|
+
(let [sym (first method)
|
|
82
|
+
ns (or (some->> sym resolve meta :ns str) "clojure.core")]
|
|
83
|
+
[(symbol ns (name sym)) (-> method second count)]))))
|
|
84
|
+
|
|
85
|
+
#?(:clj
|
|
86
|
+
(defn- dedupe-interfaces [deftype-form]
|
|
87
|
+
;; get the interfaces list, remove any duplicates, similar to remove-nil-implements in potemkin
|
|
88
|
+
;; verified w/ deftype impl in compiler:
|
|
89
|
+
;; (deftype* tagname classname [fields] :implements [interfaces] :tag tagname methods*)
|
|
90
|
+
(let [[deftype* tagname classname fields implements interfaces & rest] deftype-form]
|
|
91
|
+
(when (or (not= deftype* 'deftype*) (not= implements :implements))
|
|
92
|
+
(throw (IllegalArgumentException. "deftype-form mismatch")))
|
|
93
|
+
(list* deftype* tagname classname fields implements (vec (distinct interfaces)) rest))))
|
|
94
|
+
|
|
95
|
+
#?(:clj
|
|
96
|
+
(defn- make-record-updatable-clj [name fields & impls]
|
|
97
|
+
(let [impl-map (->> impls (map (juxt get-sig identity)) (filter first) (into {}))
|
|
98
|
+
body (macroexpand-1 (list* 'defrecord name fields impls))]
|
|
99
|
+
(postwalk
|
|
100
|
+
(fn [form]
|
|
101
|
+
(if (and (sequential? form) (= 'deftype* (first form)))
|
|
102
|
+
(->> form
|
|
103
|
+
dedupe-interfaces
|
|
104
|
+
(remove (fn [method]
|
|
105
|
+
(when-let [impl (-> method get-sig impl-map)]
|
|
106
|
+
(not= method impl)))))
|
|
107
|
+
form))
|
|
108
|
+
body))))
|
|
109
|
+
|
|
110
|
+
;; This doesn't work, it creates duplicate implementation warnings.
|
|
111
|
+
#_(:clj
|
|
112
|
+
(defn- make-record-updatable-cljs [name fields & impls]
|
|
113
|
+
`(defrecord ~name ~fields ~@impls)))
|
|
114
|
+
|
|
115
|
+
#?(:clj
|
|
116
|
+
(defn- make-record-updatable-cljs [name fields & impls]
|
|
117
|
+
`(do
|
|
118
|
+
(defrecord ~name ~fields)
|
|
119
|
+
(extend-type ~name ~@impls))))
|
|
120
|
+
|
|
121
|
+
#?(:clj
|
|
122
|
+
(defmacro defrecord-updatable [name fields & impls]
|
|
123
|
+
`(if-cljs
|
|
124
|
+
~(apply make-record-updatable-cljs name fields impls)
|
|
125
|
+
~(apply make-record-updatable-clj name fields impls))))
|
|
126
|
+
|
|
127
|
+
;; TxReport
|
|
128
|
+
|
|
129
|
+
(defrecord TxReport [db-before db-after tx-data tempids tx-meta])
|
|
130
|
+
|
|
131
|
+
;; DB
|
|
132
|
+
|
|
133
|
+
(defn- date? [d]
|
|
134
|
+
#?(:cljs (instance? js/Date d)
|
|
135
|
+
:clj (instance? Date d)))
|
|
136
|
+
|
|
137
|
+
(defn- date<= [^Date a ^Date b]
|
|
138
|
+
#?(:cljs (not (< (.getTime b) (.getTime a)))
|
|
139
|
+
:clj (not (.before b a))))
|
|
140
|
+
|
|
141
|
+
(defn- as-of-pred
|
|
142
|
+
"Create an as-of predicate, *including* the time-point"
|
|
143
|
+
[time-point]
|
|
144
|
+
(if (date? time-point)
|
|
145
|
+
(fn [^Datom d] (date<= (.-v d) time-point))
|
|
146
|
+
(fn [^Datom d] (<= (dd/datom-tx d) time-point))))
|
|
147
|
+
|
|
148
|
+
(defn- since-pred
|
|
149
|
+
"Create a since predicate, *excluding* the time-point. The opposite of `as-of-pred`."
|
|
150
|
+
[time-point]
|
|
151
|
+
(complement (as-of-pred time-point)))
|
|
152
|
+
|
|
153
|
+
(defn assemble-datoms-xform [db]
|
|
154
|
+
(mapcat
|
|
155
|
+
(fn [[[_ a] datoms]]
|
|
156
|
+
(if (dbu/multival? db a)
|
|
157
|
+
(->> datoms
|
|
158
|
+
(sort-by datom-tx)
|
|
159
|
+
(reduce (fn [current-datoms ^Datom datom]
|
|
160
|
+
(if (datom-added datom)
|
|
161
|
+
(assoc current-datoms (.-v datom) datom)
|
|
162
|
+
(dissoc current-datoms (.-v datom))))
|
|
163
|
+
{})
|
|
164
|
+
vals)
|
|
165
|
+
(let [last-ea-tx (apply max (map datom-tx datoms))
|
|
166
|
+
current-ea-datom (first (filter #(and (datom-added %) (= last-ea-tx (datom-tx %)))
|
|
167
|
+
datoms))]
|
|
168
|
+
(if current-ea-datom
|
|
169
|
+
[current-ea-datom]
|
|
170
|
+
[]))))))
|
|
171
|
+
|
|
172
|
+
(defn temporal-datom-filter [datoms pred db]
|
|
173
|
+
(let [filtered-tx-ids (dbu/filter-txInstant datoms pred db)]
|
|
174
|
+
(filter (fn [^Datom d]
|
|
175
|
+
(contains? filtered-tx-ids
|
|
176
|
+
(datom-tx d))))))
|
|
177
|
+
|
|
178
|
+
(defn- post-process-datoms [datoms db context]
|
|
179
|
+
(let [xform (dbi/context-xform context)
|
|
180
|
+
time-pred (dbi/context-time-pred context)]
|
|
181
|
+
(cond
|
|
182
|
+
|
|
183
|
+
time-pred
|
|
184
|
+
(let [time-xform (temporal-datom-filter datoms time-pred db)]
|
|
185
|
+
(if (dbi/context-historical? context)
|
|
186
|
+
(into [] (dbi/nil-comp time-xform xform) datoms)
|
|
187
|
+
(->> datoms
|
|
188
|
+
(transduce time-xform
|
|
189
|
+
(group-by-step (fn [^Datom datom]
|
|
190
|
+
[(.-e datom) (.-a datom)])))
|
|
191
|
+
(into [] (dbi/nil-comp (assemble-datoms-xform db) xform)))))
|
|
192
|
+
|
|
193
|
+
xform (into [] xform datoms)
|
|
194
|
+
|
|
195
|
+
:else datoms)))
|
|
196
|
+
|
|
197
|
+
(defn db-transient [db]
|
|
198
|
+
(-> db
|
|
199
|
+
(update :eavt di/-transient)
|
|
200
|
+
(update :aevt di/-transient)
|
|
201
|
+
(update :avet di/-transient)))
|
|
202
|
+
|
|
203
|
+
(defn db-persistent! [db]
|
|
204
|
+
(-> db
|
|
205
|
+
(update :eavt di/-persistent!)
|
|
206
|
+
(update :aevt di/-persistent!)
|
|
207
|
+
(update :avet di/-persistent!)))
|
|
208
|
+
|
|
209
|
+
(defn contextual-search-fn [context]
|
|
210
|
+
(case (dbi/context-temporal? context)
|
|
211
|
+
true dbs/temporal-search
|
|
212
|
+
false dbs/search-current-indices))
|
|
213
|
+
|
|
214
|
+
(defn contextual-search [db pattern context]
|
|
215
|
+
(-> ((contextual-search-fn context) db pattern)
|
|
216
|
+
(post-process-datoms db context)))
|
|
217
|
+
|
|
218
|
+
(defn contextual-batch-search [db pattern-mask batch-fn context]
|
|
219
|
+
(-> ((contextual-search-fn context) db pattern-mask batch-fn)
|
|
220
|
+
(post-process-datoms db context)))
|
|
221
|
+
|
|
222
|
+
(defn contextual-datoms [db index-type cs context]
|
|
223
|
+
(-> (case (dbi/context-temporal? context)
|
|
224
|
+
true (dbu/temporal-datoms db index-type cs)
|
|
225
|
+
false (di/-slice
|
|
226
|
+
(get db index-type)
|
|
227
|
+
(dbu/components->pattern db index-type cs e0 tx0)
|
|
228
|
+
(dbu/components->pattern db index-type cs emax txmax)
|
|
229
|
+
index-type))
|
|
230
|
+
(post-process-datoms db context)))
|
|
231
|
+
|
|
232
|
+
(defn contextual-seek-datoms [db index-type cs context]
|
|
233
|
+
(-> (case (dbi/context-temporal? context)
|
|
234
|
+
true (dbs/temporal-seek-datoms db index-type cs)
|
|
235
|
+
false (di/-slice (get db index-type)
|
|
236
|
+
(dbu/components->pattern db index-type cs e0 tx0)
|
|
237
|
+
(datom emax nil nil txmax)
|
|
238
|
+
index-type))
|
|
239
|
+
(post-process-datoms db context)))
|
|
240
|
+
|
|
241
|
+
(defn contextual-rseek-datoms [db index-type cs context]
|
|
242
|
+
(-> (case (dbi/context-temporal? context)
|
|
243
|
+
true (dbs/temporal-rseek-datoms db index-type cs)
|
|
244
|
+
false (-> (di/-slice (get db index-type)
|
|
245
|
+
(dbu/components->pattern db index-type cs e0 tx0)
|
|
246
|
+
(datom emax nil nil txmax)
|
|
247
|
+
index-type)
|
|
248
|
+
vec
|
|
249
|
+
rseq))
|
|
250
|
+
(post-process-datoms db context)))
|
|
251
|
+
|
|
252
|
+
(defn contextual-index-range [db avet attr start end context]
|
|
253
|
+
(let [temporal? (dbi/context-temporal? context)
|
|
254
|
+
current-db (dbi/context-current-db context)]
|
|
255
|
+
(assert (or (not temporal?) current-db))
|
|
256
|
+
(-> (case temporal?
|
|
257
|
+
true (dbs/temporal-index-range db current-db attr start end)
|
|
258
|
+
false (do (when-not (dbu/indexing? db attr)
|
|
259
|
+
(raise "Attribute"
|
|
260
|
+
attr "should be marked as :db/index true" {}))
|
|
261
|
+
|
|
262
|
+
(dbu/validate-attr
|
|
263
|
+
attr (list '-index-range 'db attr start end) db)
|
|
264
|
+
(di/-slice
|
|
265
|
+
avet
|
|
266
|
+
(dbu/resolve-datom db nil attr start nil e0 tx0)
|
|
267
|
+
(dbu/resolve-datom db nil attr end nil emax txmax)
|
|
268
|
+
:avet)))
|
|
269
|
+
(post-process-datoms db context))))
|
|
270
|
+
|
|
271
|
+
(defn deeper-index-range [origin-db db attr start end context]
|
|
272
|
+
(dbi/-index-range origin-db
|
|
273
|
+
attr
|
|
274
|
+
start
|
|
275
|
+
end
|
|
276
|
+
(dbi/context-set-current-db-if-not-set context db)))
|
|
277
|
+
|
|
278
|
+
(defrecord-updatable DB [schema eavt aevt avet temporal-eavt temporal-aevt temporal-avet max-eid max-tx op-count rschema hash config system-entities ident-ref-map ref-ident-map meta]
|
|
279
|
+
#?@(:cljs
|
|
280
|
+
[IHash (-hash [db] (.-hash db))
|
|
281
|
+
IEquiv (-equiv [db other] (equiv-db db other))
|
|
282
|
+
ISeqable (-seq [db] (di/-seq (.-eavt db)))
|
|
283
|
+
IReversible (-rseq [db] (-rseq (.-eavt db)))
|
|
284
|
+
ICounted (-count [db] (count (.-eavt db)))
|
|
285
|
+
IEmptyableCollection (-empty [db] (empty-db (ds/get-user-schema db)))
|
|
286
|
+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
|
|
287
|
+
IEditableCollection (-as-transient [db] (db-transient db))
|
|
288
|
+
ITransientCollection (-conj! [db key] (throw (ex-info "datahike.DB/conj! is not supported" {})))
|
|
289
|
+
(-persistent! [db] (db-persistent! db))]
|
|
290
|
+
|
|
291
|
+
:clj
|
|
292
|
+
[Object (hashCode [db] hash)
|
|
293
|
+
clojure.lang.IHashEq (hasheq [db] hash)
|
|
294
|
+
Seqable (seq [db] (di/-seq eavt))
|
|
295
|
+
IPersistentCollection
|
|
296
|
+
(count [db] (di/-count eavt))
|
|
297
|
+
(equiv [db other] (equiv-db db other))
|
|
298
|
+
(empty [db] (empty-db (ds/get-user-schema db)))
|
|
299
|
+
IEditableCollection
|
|
300
|
+
(asTransient [db] (db-transient db))
|
|
301
|
+
ITransientCollection
|
|
302
|
+
(conj [db key] (throw (ex-info "datahike.DB/conj! is not supported" {})))
|
|
303
|
+
(persistent [db] (db-persistent! db))])
|
|
304
|
+
|
|
305
|
+
dbi/IDB
|
|
306
|
+
(-schema [db] (.-schema db))
|
|
307
|
+
(-rschema [db] (.-rschema db))
|
|
308
|
+
(-system-entities [db] (.-system-entities db))
|
|
309
|
+
(-attrs-by [db property] ((.-rschema db) property))
|
|
310
|
+
(-temporal-index? [db] (dbi/-keep-history? db))
|
|
311
|
+
(-keep-history? [db] (:keep-history? (.-config db)))
|
|
312
|
+
(-max-tx [db] (.-max-tx db))
|
|
313
|
+
(-max-eid [db] (.-max-eid db))
|
|
314
|
+
(-config [db] (.-config db))
|
|
315
|
+
(-ref-for [db a-ident]
|
|
316
|
+
(if (:attribute-refs? (.-config db))
|
|
317
|
+
(let [ref (get (.-ident-ref-map db) a-ident)]
|
|
318
|
+
(when (nil? ref)
|
|
319
|
+
(warn (str "Attribute " a-ident " has not been found in database")))
|
|
320
|
+
ref)
|
|
321
|
+
a-ident))
|
|
322
|
+
(-ident-for [db a-ref]
|
|
323
|
+
(if (:attribute-refs? (.-config db))
|
|
324
|
+
(let [a-ident (get (.-ref-ident-map db) a-ref)]
|
|
325
|
+
(when (nil? a-ident)
|
|
326
|
+
(warn (str "Attribute with reference number " a-ref " has not been found in database")))
|
|
327
|
+
a-ident)
|
|
328
|
+
a-ref))
|
|
329
|
+
|
|
330
|
+
dbi/ISearch
|
|
331
|
+
(-search-context [db] dbi/base-context)
|
|
332
|
+
(-search [db pattern context]
|
|
333
|
+
(contextual-search db pattern context))
|
|
334
|
+
(-batch-search [db pattern-mask batch-fn context]
|
|
335
|
+
(contextual-batch-search db pattern-mask batch-fn context))
|
|
336
|
+
|
|
337
|
+
dbi/IIndexAccess
|
|
338
|
+
(-datoms [db index-type cs context]
|
|
339
|
+
(contextual-datoms db index-type cs context))
|
|
340
|
+
|
|
341
|
+
(-seek-datoms [db index-type cs context]
|
|
342
|
+
(contextual-seek-datoms db index-type cs context))
|
|
343
|
+
|
|
344
|
+
(-rseek-datoms [db index-type cs context]
|
|
345
|
+
(contextual-rseek-datoms db index-type cs context))
|
|
346
|
+
|
|
347
|
+
(-index-range [db attr start end context]
|
|
348
|
+
(contextual-index-range db (.-avet db) attr start end context))
|
|
349
|
+
|
|
350
|
+
data/EqualityPartition
|
|
351
|
+
(equality-partition [x] :datahike/db)
|
|
352
|
+
|
|
353
|
+
data/Diff
|
|
354
|
+
(diff-similar [a b]
|
|
355
|
+
(let [datoms-a (di/-slice (:eavt a) (datom e0 nil nil tx0) (datom emax nil nil txmax) :eavt)
|
|
356
|
+
datoms-b (di/-slice (:eavt b) (datom e0 nil nil tx0) (datom emax nil nil txmax) :eavt)]
|
|
357
|
+
(dd/diff-sorted datoms-a datoms-b dd/cmp-datoms-eavt-quick))))
|
|
358
|
+
|
|
359
|
+
;; FilteredDB
|
|
360
|
+
|
|
361
|
+
(defrecord-updatable FilteredDB [unfiltered-db pred]
|
|
362
|
+
#?@(:cljs
|
|
363
|
+
[IEquiv (-equiv [db other] (equiv-db db other))
|
|
364
|
+
ISeqable (-seq [db] (dbi/datoms db :eavt []))
|
|
365
|
+
ICounted (-count [db] (count (dbi/datoms db :eavt [])))
|
|
366
|
+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
|
|
367
|
+
|
|
368
|
+
IEmptyableCollection (-empty [_] (throw (js/Error. "-empty is not supported on FilteredDB")))
|
|
369
|
+
|
|
370
|
+
ILookup (-lookup ([_ _] (throw (js/Error. "-lookup is not supported on FilteredDB")))
|
|
371
|
+
([_ _ _] (throw (js/Error. "-lookup is not supported on FilteredDB"))))
|
|
372
|
+
|
|
373
|
+
IAssociative
|
|
374
|
+
(-contains-key? [_ _] (throw (js/Error. "-contains-key? is not supported on FilteredDB")))
|
|
375
|
+
(-assoc [_ _ _] (throw (js/Error. "-assoc is not supported on FilteredDB")))]
|
|
376
|
+
|
|
377
|
+
:clj
|
|
378
|
+
[IPersistentCollection
|
|
379
|
+
(count [db] (count (dbi/datoms db :eavt [])))
|
|
380
|
+
(equiv [db o] (equiv-db db o))
|
|
381
|
+
(cons [db [k v]] (throw (UnsupportedOperationException. "cons is not supported on FilteredDB")))
|
|
382
|
+
(empty [db] (throw (UnsupportedOperationException. "empty is not supported on FilteredDB")))
|
|
383
|
+
|
|
384
|
+
Seqable (seq [db] (dbi/datoms db :eavt []))
|
|
385
|
+
|
|
386
|
+
clojure.lang.ILookup (valAt [db k] (throw (UnsupportedOperationException. "valAt/2 is not supported on FilteredDB")))
|
|
387
|
+
(valAt [db k nf] (throw (UnsupportedOperationException. "valAt/3 is not supported on FilteredDB")))
|
|
388
|
+
clojure.lang.IKeywordLookup (getLookupThunk [db k]
|
|
389
|
+
(throw (UnsupportedOperationException. "getLookupThunk is not supported on FilteredDB")))
|
|
390
|
+
|
|
391
|
+
Associative
|
|
392
|
+
(containsKey [e k] (throw (UnsupportedOperationException. "containsKey is not supported on FilteredDB")))
|
|
393
|
+
(entryAt [db k] (throw (UnsupportedOperationException. "entryAt is not supported on FilteredDB")))
|
|
394
|
+
(assoc [db k v] (throw (UnsupportedOperationException. "assoc is not supported on FilteredDB")))])
|
|
395
|
+
|
|
396
|
+
dbi/IDB
|
|
397
|
+
(-schema [db] (dbi/-schema (.-unfiltered-db db)))
|
|
398
|
+
(-rschema [db] (dbi/-rschema (.-unfiltered-db db)))
|
|
399
|
+
(-system-entities [db] (dbi/-system-entities (.-unfiltered-db db)))
|
|
400
|
+
(-attrs-by [db property] (dbi/-attrs-by (.-unfiltered-db db) property))
|
|
401
|
+
(-temporal-index? [db] (dbi/-keep-history? db))
|
|
402
|
+
(-keep-history? [db] (dbi/-keep-history? (.-unfiltered-db db)))
|
|
403
|
+
(-max-tx [db] (dbi/-max-tx (.-unfiltered-db db)))
|
|
404
|
+
(-max-eid [db] (dbi/-max-eid (.-unfiltered-db db)))
|
|
405
|
+
(-config [db] (dbi/-config (.-unfiltered-db db)))
|
|
406
|
+
(-ref-for [db a-ident] (dbi/-ref-for (.-unfiltered-db db) a-ident))
|
|
407
|
+
(-ident-for [db a-ref] (dbi/-ident-for (.-unfiltered-db db) a-ref))
|
|
408
|
+
|
|
409
|
+
dbi/ISearch
|
|
410
|
+
(-search-context [db] (dbi/context-with-xform-after
|
|
411
|
+
(dbi/-search-context (.-unfiltered-db db))
|
|
412
|
+
(filter (.-pred db))))
|
|
413
|
+
(-search [db pattern context]
|
|
414
|
+
(dbi/-search (.-unfiltered-db db) pattern context))
|
|
415
|
+
(-batch-search [db pattern-mask batch-fn context]
|
|
416
|
+
(dbi/-batch-search (.-unfiltered-db db) pattern-mask batch-fn context))
|
|
417
|
+
|
|
418
|
+
dbi/IIndexAccess
|
|
419
|
+
(-datoms [db index cs context]
|
|
420
|
+
(dbi/-datoms (.-unfiltered-db db) index cs context))
|
|
421
|
+
|
|
422
|
+
(-seek-datoms [db index cs context]
|
|
423
|
+
(dbi/-seek-datoms (.-unfiltered-db db) index cs context))
|
|
424
|
+
|
|
425
|
+
(-rseek-datoms [db index cs context]
|
|
426
|
+
(dbi/-rseek-datoms (.-unfiltered-db db) index cs context))
|
|
427
|
+
|
|
428
|
+
(-index-range [db attr start end context]
|
|
429
|
+
(deeper-index-range (.-unfiltered-db db)
|
|
430
|
+
db
|
|
431
|
+
attr
|
|
432
|
+
start end
|
|
433
|
+
context)))
|
|
434
|
+
|
|
435
|
+
;; HistoricalDB
|
|
436
|
+
|
|
437
|
+
(defrecord-updatable HistoricalDB [origin-db]
|
|
438
|
+
#?@(:cljs
|
|
439
|
+
[IEquiv (-equiv [db other] (equiv-db db other))
|
|
440
|
+
ISeqable (-seq [db] (dbi/datoms db :eavt []))
|
|
441
|
+
ICounted (-count [db] (count (dbi/datoms db :eavt [])))
|
|
442
|
+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
|
|
443
|
+
|
|
444
|
+
IEmptyableCollection (-empty [_] (throw (js/Error. "-empty is not supported on HistoricalDB")))
|
|
445
|
+
|
|
446
|
+
ILookup (-lookup ([_ _] (throw (js/Error. "-lookup is not supported on HistoricalDB")))
|
|
447
|
+
([_ _ _] (throw (js/Error. "-lookup is not supported on HistoricalDB"))))
|
|
448
|
+
|
|
449
|
+
IAssociative
|
|
450
|
+
(-contains-key? [_ _] (throw (js/Error. "-contains-key? is not supported on HistoricalDB")))
|
|
451
|
+
(-assoc [_ _ _] (throw (js/Error. "-assoc is not supported on HistoricalDB")))]
|
|
452
|
+
:clj
|
|
453
|
+
[IPersistentCollection
|
|
454
|
+
(count [db] (count (dbi/datoms db :eavt [])))
|
|
455
|
+
(equiv [db o] (equiv-db db o))
|
|
456
|
+
(cons [db [k v]] (throw (UnsupportedOperationException. "cons is not supported on HistoricalDB")))
|
|
457
|
+
(empty [db] (throw (UnsupportedOperationException. "empty is not supported on HistoricalDB")))
|
|
458
|
+
|
|
459
|
+
Seqable
|
|
460
|
+
(seq [db] (dbi/datoms db :eavt []))
|
|
461
|
+
|
|
462
|
+
Associative
|
|
463
|
+
(assoc [db k v] (throw (UnsupportedOperationException. "assoc is not supported on HistoricalDB")))])
|
|
464
|
+
|
|
465
|
+
dbi/IDB
|
|
466
|
+
(-schema [db] (dbi/-schema (.-origin-db db)))
|
|
467
|
+
(-rschema [db] (dbi/-rschema (.-origin-db db)))
|
|
468
|
+
(-system-entities [db] (dbi/-system-entities (.-origin-db db)))
|
|
469
|
+
(-attrs-by [db property] (dbi/-attrs-by (.-origin-db db) property))
|
|
470
|
+
(-temporal-index? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
471
|
+
(-keep-history? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
472
|
+
(-max-tx [db] (dbi/-max-tx (.-origin-db db)))
|
|
473
|
+
(-max-eid [db] (dbi/-max-eid (.-origin-db db)))
|
|
474
|
+
(-config [db] (dbi/-config (.-origin-db db)))
|
|
475
|
+
(-ref-for [db a-ident] (dbi/-ref-for (.-origin-db db) a-ident))
|
|
476
|
+
(-ident-for [db a-ref] (dbi/-ident-for (.-origin-db db) a-ref))
|
|
477
|
+
|
|
478
|
+
dbi/IHistory
|
|
479
|
+
(-time-point [db] nil)
|
|
480
|
+
(-origin [db] (.-origin-db db))
|
|
481
|
+
|
|
482
|
+
dbi/ISearch
|
|
483
|
+
(-search-context [db]
|
|
484
|
+
(-> (.-origin-db db)
|
|
485
|
+
dbi/-search-context
|
|
486
|
+
dbi/context-with-history))
|
|
487
|
+
(-search [db pattern context]
|
|
488
|
+
(dbi/-search (.-origin-db db) pattern context))
|
|
489
|
+
(-batch-search [db pattern-mask batch-fn context]
|
|
490
|
+
(dbi/-batch-search (.-origin-db db) pattern-mask batch-fn context))
|
|
491
|
+
|
|
492
|
+
dbi/IIndexAccess
|
|
493
|
+
(-datoms [db index-type cs context] (dbi/-datoms (.-origin-db db) index-type cs context))
|
|
494
|
+
|
|
495
|
+
(-seek-datoms [db index-type cs context] (dbi/-seek-datoms (.-origin-db db) index-type cs context))
|
|
496
|
+
|
|
497
|
+
(-rseek-datoms [db index-type cs context] (dbi/-rseek-datoms (.-origin-db db) index-type cs context))
|
|
498
|
+
|
|
499
|
+
(-index-range [db attr start end context] (deeper-index-range (.-origin-db db) db attr start end context)))
|
|
500
|
+
|
|
501
|
+
;; AsOfDB
|
|
502
|
+
|
|
503
|
+
(defrecord-updatable AsOfDB [origin-db time-point]
|
|
504
|
+
#?@(:cljs
|
|
505
|
+
[IEquiv (-equiv [db other] (equiv-db db other))
|
|
506
|
+
ISeqable (-seq [db] (dbi/datoms db :eavt []))
|
|
507
|
+
ICounted (-count [db] (count (dbi/datoms db :eavt [])))
|
|
508
|
+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
|
|
509
|
+
|
|
510
|
+
IEmptyableCollection (-empty [_] (throw (js/Error. "-empty is not supported on AsOfDB")))
|
|
511
|
+
|
|
512
|
+
ILookup (-lookup ([_ _] (throw (js/Error. "-lookup is not supported on AsOfDB")))
|
|
513
|
+
([_ _ _] (throw (js/Error. "-lookup is not supported on AsOfDB"))))
|
|
514
|
+
|
|
515
|
+
IAssociative
|
|
516
|
+
(-contains-key? [_ _] (throw (js/Error. "-contains-key? is not supported on AsOfDB")))
|
|
517
|
+
(-assoc [_ _ _] (throw (js/Error. "-assoc is not supported on AsOfDB")))]
|
|
518
|
+
:clj
|
|
519
|
+
[IPersistentCollection
|
|
520
|
+
(count [db] (count (dbi/datoms db :eavt [])))
|
|
521
|
+
(equiv [db o] (equiv-db db o))
|
|
522
|
+
(cons [db [k v]] (throw (UnsupportedOperationException. "cons is not supported on AsOfDB")))
|
|
523
|
+
(empty [db] (throw (UnsupportedOperationException. "empty is not supported on AsOfDB")))
|
|
524
|
+
|
|
525
|
+
Seqable
|
|
526
|
+
(seq [db] (dbi/datoms db :eavt []))
|
|
527
|
+
|
|
528
|
+
Associative
|
|
529
|
+
(assoc [db k v] (throw (UnsupportedOperationException. "assoc is not supported on AsOfDB")))])
|
|
530
|
+
|
|
531
|
+
dbi/IDB
|
|
532
|
+
(-schema [db] (dbi/-schema (.-origin-db db)))
|
|
533
|
+
(-rschema [db] (dbi/-rschema (.-origin-db db)))
|
|
534
|
+
(-system-entities [db] (dbi/-system-entities (.-origin-db db)))
|
|
535
|
+
(-attrs-by [db property] (dbi/-attrs-by (.-origin-db db) property))
|
|
536
|
+
(-temporal-index? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
537
|
+
(-keep-history? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
538
|
+
(-max-tx [db] (dbi/-max-tx (.-origin-db db)))
|
|
539
|
+
(-max-eid [db] (dbi/-max-eid (.-origin-db db)))
|
|
540
|
+
(-config [db] (dbi/-config (.-origin-db db)))
|
|
541
|
+
(-ref-for [db a-ident] (dbi/-ref-for (.-origin-db db) a-ident))
|
|
542
|
+
(-ident-for [db a-ref] (dbi/-ident-for (.-origin-db db) a-ref))
|
|
543
|
+
|
|
544
|
+
dbi/IHistory
|
|
545
|
+
(-time-point [db] (.-time-point db))
|
|
546
|
+
(-origin [db] (.-origin-db db))
|
|
547
|
+
|
|
548
|
+
dbi/ISearch
|
|
549
|
+
(-search-context [db] (dbi/context-with-temporal-timepred
|
|
550
|
+
(dbi/-search-context (.-origin-db db))
|
|
551
|
+
(as-of-pred (.-time-point db))))
|
|
552
|
+
(-search [db pattern context]
|
|
553
|
+
(dbi/-search (.-origin-db db) pattern context))
|
|
554
|
+
(-batch-search [db pattern batch-fn context]
|
|
555
|
+
(dbi/-batch-search (.-origin-db db) pattern batch-fn context))
|
|
556
|
+
|
|
557
|
+
dbi/IIndexAccess
|
|
558
|
+
(-datoms [db index-type cs context]
|
|
559
|
+
(dbi/-datoms (.-origin-db db) index-type cs context))
|
|
560
|
+
|
|
561
|
+
(-seek-datoms [db index-type cs context]
|
|
562
|
+
(dbi/-seek-datoms (.-origin-db db) index-type cs context))
|
|
563
|
+
|
|
564
|
+
(-rseek-datoms [db index-type cs context]
|
|
565
|
+
(dbi/-rseek-datoms (.-origin-db db) index-type cs context))
|
|
566
|
+
|
|
567
|
+
(-index-range [db attr start end context]
|
|
568
|
+
(deeper-index-range (.-origin-db db) db attr start end context)))
|
|
569
|
+
|
|
570
|
+
(defrecord-updatable SinceDB [origin-db time-point]
|
|
571
|
+
#?@(:cljs
|
|
572
|
+
[IEquiv (-equiv [db other] (equiv-db db other))
|
|
573
|
+
ISeqable (-seq [db] (dbi/datoms db :eavt []))
|
|
574
|
+
ICounted (-count [db] (count (dbi/datoms db :eavt [])))
|
|
575
|
+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
|
|
576
|
+
|
|
577
|
+
IEmptyableCollection (-empty [_] (throw (js/Error. "-empty is not supported on SinceDB")))
|
|
578
|
+
|
|
579
|
+
ILookup (-lookup ([_ _] (throw (js/Error. "-lookup is not supported on SinceDB")))
|
|
580
|
+
([_ _ _] (throw (js/Error. "-lookup is not supported on SinceDB"))))
|
|
581
|
+
|
|
582
|
+
IAssociative
|
|
583
|
+
(-contains-key? [_ _] (throw (js/Error. "-contains-key? is not supported on SinceDB")))
|
|
584
|
+
(-assoc [_ _ _] (throw (js/Error. "-assoc is not supported on SinceDB")))]
|
|
585
|
+
:clj
|
|
586
|
+
[IPersistentCollection
|
|
587
|
+
(count [db] (count (dbi/datoms db :eavt [])))
|
|
588
|
+
(equiv [db o] (equiv-db db o))
|
|
589
|
+
(cons [db [k v]] (throw (UnsupportedOperationException. "cons is not supported on SinceDB")))
|
|
590
|
+
(empty [db] (throw (UnsupportedOperationException. "empty is not supported on SinceDB")))
|
|
591
|
+
|
|
592
|
+
Seqable
|
|
593
|
+
(seq [db] (dbi/datoms db :eavt []))
|
|
594
|
+
|
|
595
|
+
Associative
|
|
596
|
+
(assoc [db k v] (throw (UnsupportedOperationException. "assoc is not supported on SinceDB")))])
|
|
597
|
+
|
|
598
|
+
dbi/IDB
|
|
599
|
+
(-schema [db] (dbi/-schema (.-origin-db db)))
|
|
600
|
+
(-rschema [db] (dbi/-rschema (.-origin-db db)))
|
|
601
|
+
(-system-entities [db] (dbi/-system-entities (.-origin-db db)))
|
|
602
|
+
(-attrs-by [db property] (dbi/-attrs-by (.-origin-db db) property))
|
|
603
|
+
(-temporal-index? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
604
|
+
(-keep-history? [db] (dbi/-keep-history? (.-origin-db db)))
|
|
605
|
+
(-max-tx [db] (dbi/-max-tx (.-origin-db db)))
|
|
606
|
+
(-max-eid [db] (dbi/-max-eid (.-origin-db db)))
|
|
607
|
+
(-config [db] (dbi/-config (.-origin-db db)))
|
|
608
|
+
(-ref-for [db a-ident] (dbi/-ref-for (.-origin-db db) a-ident))
|
|
609
|
+
(-ident-for [db a-ref] (dbi/-ident-for (.-origin-db db) a-ref))
|
|
610
|
+
|
|
611
|
+
dbi/IHistory
|
|
612
|
+
(-time-point [db] (.-time-point db))
|
|
613
|
+
(-origin [db] (.-origin-db db))
|
|
614
|
+
|
|
615
|
+
dbi/ISearch
|
|
616
|
+
(-search-context [db] (dbi/context-with-temporal-timepred
|
|
617
|
+
(dbi/-search-context (.-origin-db db))
|
|
618
|
+
(since-pred (.-time-point db))))
|
|
619
|
+
(-search [db pattern context]
|
|
620
|
+
(dbi/-search (.-origin-db db) pattern context))
|
|
621
|
+
(-batch-search [db pattern batch-fn context]
|
|
622
|
+
(dbi/-batch-search (.-origin-db db) pattern batch-fn context))
|
|
623
|
+
|
|
624
|
+
dbi/IIndexAccess
|
|
625
|
+
(dbi/-datoms [db index-type cs context]
|
|
626
|
+
(dbi/-datoms (.-origin-db db) index-type cs context))
|
|
627
|
+
|
|
628
|
+
(dbi/-seek-datoms [db index-type cs context]
|
|
629
|
+
(dbi/-seek-datoms (.-origin-db db) index-type cs context))
|
|
630
|
+
|
|
631
|
+
(dbi/-rseek-datoms [db index-type cs context]
|
|
632
|
+
(dbi/-rseek-datoms (.-origin-db db) index-type cs context))
|
|
633
|
+
|
|
634
|
+
(dbi/-index-range [db attr start end context]
|
|
635
|
+
(deeper-index-range (.-origin-db db)
|
|
636
|
+
db
|
|
637
|
+
attr
|
|
638
|
+
start end
|
|
639
|
+
context)))
|
|
640
|
+
|
|
641
|
+
(defn- equiv-db-index [x y]
|
|
642
|
+
(loop [xs (seq x)
|
|
643
|
+
ys (seq y)]
|
|
644
|
+
(cond
|
|
645
|
+
(nil? xs) (nil? ys)
|
|
646
|
+
(= (first xs) (first ys)) (recur (next xs) (next ys))
|
|
647
|
+
:else false)))
|
|
648
|
+
|
|
649
|
+
(defn- equiv-db [db other]
|
|
650
|
+
(and (or (instance? DB other) (instance? FilteredDB other))
|
|
651
|
+
(or (not (instance? DB other)) (= (hash db) (hash other)))
|
|
652
|
+
(= (dbi/-schema db) (dbi/-schema other))
|
|
653
|
+
(equiv-db-index (dbi/datoms db :eavt []) (dbi/datoms other :eavt []))))
|
|
654
|
+
|
|
655
|
+
#?(:cljs
|
|
656
|
+
(defn pr-db [db w opts]
|
|
657
|
+
(-write w "#datahike/DB {")
|
|
658
|
+
(-write w (str ":max-tx " (dbi/-max-tx db) " "))
|
|
659
|
+
(-write w (str ":max-eid " (dbi/-max-eid db) " "))
|
|
660
|
+
(-write w "}")))
|
|
661
|
+
|
|
662
|
+
#?(:clj
|
|
663
|
+
(do
|
|
664
|
+
(defn pr-db [db, ^Writer w]
|
|
665
|
+
(.write w (str "#datahike/DB {"))
|
|
666
|
+
(.write w ":store-id [")
|
|
667
|
+
(.write w (pr-str (store/store-identity (:store (dbi/-config db)))))
|
|
668
|
+
(.write w " ")
|
|
669
|
+
(.write w (pr-str (:branch (dbi/-config db))))
|
|
670
|
+
(.write w "] ")
|
|
671
|
+
(.write w (str ":commit-id " (pr-str (:datahike/commit-id (:meta db))) " "))
|
|
672
|
+
(.write w (str ":max-tx " (dbi/-max-tx db) " "))
|
|
673
|
+
(.write w (str ":max-eid " (dbi/-max-eid db)))
|
|
674
|
+
(.write w "}"))
|
|
675
|
+
|
|
676
|
+
(defn pr-hist-db [db ^Writer w flavor time-point?]
|
|
677
|
+
(.write w (str "#datahike/" flavor " {"))
|
|
678
|
+
(.write w ":origin ")
|
|
679
|
+
(binding [*out* w]
|
|
680
|
+
(pr (dbi/-origin db)))
|
|
681
|
+
(when time-point?
|
|
682
|
+
(.write w " :time-point ")
|
|
683
|
+
(binding [*out* w]
|
|
684
|
+
(pr (dbi/-time-point db))))
|
|
685
|
+
(.write w "}"))
|
|
686
|
+
|
|
687
|
+
(defmethod print-method DB [db w] (pr-db db w))
|
|
688
|
+
(defmethod print-method FilteredDB [db w] (pr-db db w)) ;; why not with "FilteredDB" ?
|
|
689
|
+
(defmethod print-method HistoricalDB [db w] (pr-hist-db db w "HistoricalDB" false))
|
|
690
|
+
(defmethod print-method AsOfDB [db w] (pr-hist-db db w "AsOfDB" true))
|
|
691
|
+
(defmethod print-method SinceDB [db w] (pr-hist-db db w "SinceDB" true))
|
|
692
|
+
|
|
693
|
+
(defmethod pp/simple-dispatch Datom [^Datom d]
|
|
694
|
+
(pp/pprint-logical-block :prefix "#datahike/Datom [" :suffix "]"
|
|
695
|
+
(pp/write-out (.-e d))
|
|
696
|
+
(.write ^Writer *out* " ")
|
|
697
|
+
(pp/pprint-newline :linear)
|
|
698
|
+
(pp/write-out (.-a d))
|
|
699
|
+
(.write ^Writer *out* " ")
|
|
700
|
+
(pp/pprint-newline :linear)
|
|
701
|
+
(pp/write-out (.-v d))
|
|
702
|
+
(.write ^Writer *out* " ")
|
|
703
|
+
(pp/pprint-newline :linear)
|
|
704
|
+
(pp/write-out (datom-tx d))))
|
|
705
|
+
|
|
706
|
+
(defn- pp-db [db ^Writer w]
|
|
707
|
+
(pp/pprint-logical-block :prefix "#datahike/DB {" :suffix "}"
|
|
708
|
+
(pp/pprint-logical-block
|
|
709
|
+
(pp/write-out :max-tx)
|
|
710
|
+
(.write ^Writer *out* " ")
|
|
711
|
+
(pp/pprint-newline :linear)
|
|
712
|
+
(pp/write-out (dbi/-max-tx db))
|
|
713
|
+
(.write ^Writer *out* " ")
|
|
714
|
+
(pp/pprint-newline :linear)
|
|
715
|
+
(pp/write-out :max-eid)
|
|
716
|
+
(.write ^Writer *out* " ")
|
|
717
|
+
(pp/pprint-newline :linear)
|
|
718
|
+
(pp/write-out (dbi/-max-eid db)))
|
|
719
|
+
(pp/pprint-newline :linear)))
|
|
720
|
+
|
|
721
|
+
(defmethod pp/simple-dispatch DB [db] (pp-db db *out*))
|
|
722
|
+
(defmethod pp/simple-dispatch FilteredDB [db] (pp-db db *out*))))
|
|
723
|
+
|
|
724
|
+
(defn- validate-schema-key [a k v expected]
|
|
725
|
+
(when-not (or (nil? v)
|
|
726
|
+
(contains? expected v))
|
|
727
|
+
(throw (ex-info (str "Bad attribute specification for " (pr-str {a {k v}}) ", expected one of " expected)
|
|
728
|
+
{:error :schema/validation
|
|
729
|
+
:attribute a
|
|
730
|
+
:key k
|
|
731
|
+
:value v}))))
|
|
732
|
+
|
|
733
|
+
(defn- validate-tuple-schema [a kv]
|
|
734
|
+
(when (= :db.type/tuple (:db/valueType kv))
|
|
735
|
+
(case (some #{:db/tupleAttrs :db/tupleTypes :db/tupleType} (keys kv))
|
|
736
|
+
:db/tupleAttrs (when (not (vector? (:db/tupleAttrs kv)))
|
|
737
|
+
(throw (ex-info (str "Bad attribute specification for " a ": {:db/tupleAttrs ...} should be a vector}")
|
|
738
|
+
{:error :schema/validation
|
|
739
|
+
:attribute a
|
|
740
|
+
:key :db/tupleAttrs})))
|
|
741
|
+
:db/tupleTypes (when (not (vector? (:db/tupleTypes kv)))
|
|
742
|
+
(throw (ex-info (str "Bad attribute specification for " a ": {:db/tupleTypes ...} should be a vector}")
|
|
743
|
+
{:error :schema/validation
|
|
744
|
+
:attribute a
|
|
745
|
+
:key :db/tupleTypes})))
|
|
746
|
+
:db/tupleType (when (not (keyword? (:db/tupleType kv)))
|
|
747
|
+
(throw (ex-info (str "Bad attribute specification for " a ": {:db/tupleType ...} should be a keyword}")
|
|
748
|
+
{:error :schema/validation
|
|
749
|
+
:attribute a
|
|
750
|
+
:key :db/tupleType}))))))
|
|
751
|
+
|
|
752
|
+
(defn- validate-schema [schema]
|
|
753
|
+
(doseq [[a-ident kv] schema]
|
|
754
|
+
(let [comp? (:db/isComponent kv false)]
|
|
755
|
+
(validate-schema-key a-ident :db/isComponent (:db/isComponent kv) #{true false})
|
|
756
|
+
(when (and comp? (not= (:db/valueType kv) :db.type/ref))
|
|
757
|
+
(throw (ex-info (str "Bad attribute specification for " a-ident ": {:db/isComponent true} should also have {:db/valueType :db.type/ref}")
|
|
758
|
+
{:error :schema/validation
|
|
759
|
+
:attribute a-ident
|
|
760
|
+
:key :db/isComponent}))))
|
|
761
|
+
(validate-schema-key a-ident :db/unique (:db/unique kv) #{:db.unique/value :db.unique/identity})
|
|
762
|
+
(validate-schema-key a-ident :db/valueType (:db/valueType kv) #{:db.type/ref :db.type/tuple})
|
|
763
|
+
(validate-schema-key a-ident :db/cardinality (:db/cardinality kv) #{:db.cardinality/one :db.cardinality/many})
|
|
764
|
+
(validate-tuple-schema a-ident kv)))
|
|
765
|
+
|
|
766
|
+
(defn to-old-schema [new-schema]
|
|
767
|
+
(if (or (vector? new-schema) (seq? new-schema))
|
|
768
|
+
(reduce
|
|
769
|
+
(fn [acc {:keys [:db/ident] :as schema-entity}]
|
|
770
|
+
(assoc acc ident schema-entity))
|
|
771
|
+
{}
|
|
772
|
+
new-schema)
|
|
773
|
+
new-schema))
|
|
774
|
+
|
|
775
|
+
(defn- validate-write-schema [schema]
|
|
776
|
+
(when-not (ds/old-schema-valid? schema)
|
|
777
|
+
(raise "Incomplete schema attributes, expected at least :db/valueType, :db/cardinality"
|
|
778
|
+
(ds/explain-old-schema schema))))
|
|
779
|
+
|
|
780
|
+
(defn init-max-eid [eavt]
|
|
781
|
+
;; solved with reverse slice first in datascript
|
|
782
|
+
(if-let [datoms (di/-slice
|
|
783
|
+
eavt
|
|
784
|
+
(datom e0 nil nil tx0)
|
|
785
|
+
(datom (dec tx0) nil nil txmax)
|
|
786
|
+
:eavt)]
|
|
787
|
+
(-> datoms vec rseq first :e) ;; :e of last datom in slice
|
|
788
|
+
e0))
|
|
789
|
+
|
|
790
|
+
(defn get-max-tx [eavt]
|
|
791
|
+
(transduce (map (fn [^Datom d] (datom-tx d))) max tx0 (di/-all eavt)))
|
|
792
|
+
|
|
793
|
+
(def ref-datoms ;; maps enums as well
|
|
794
|
+
(let [idents (reduce (fn [m {:keys [db/ident db/id]}]
|
|
795
|
+
(assoc m ident id))
|
|
796
|
+
{}
|
|
797
|
+
system-schema)]
|
|
798
|
+
(->> system-schema
|
|
799
|
+
(mapcat
|
|
800
|
+
(fn [{:keys [db/id] :as i}]
|
|
801
|
+
(reduce-kv
|
|
802
|
+
(fn [coll k v]
|
|
803
|
+
(let [v-ref (idents v)
|
|
804
|
+
;; datom val can be system schema eid (v-ref), or ident or regular (v)
|
|
805
|
+
d-val (if (and (not= k :db/ident) v-ref) v-ref v)]
|
|
806
|
+
(conj coll (dd/datom id (idents k) d-val tx0))))
|
|
807
|
+
[]
|
|
808
|
+
(dissoc i :db/id))))
|
|
809
|
+
vec)))
|
|
810
|
+
|
|
811
|
+
(defn get-ident-ref-map
|
|
812
|
+
"Maps IDs of system entities to their names (keyword) and attribute names to the attribute's specification"
|
|
813
|
+
[schema]
|
|
814
|
+
(reduce
|
|
815
|
+
(fn [m [a {:keys [db/id]}]]
|
|
816
|
+
(when a
|
|
817
|
+
(assoc m a id)))
|
|
818
|
+
{}
|
|
819
|
+
schema))
|
|
820
|
+
|
|
821
|
+
(defn ^DB empty-db
|
|
822
|
+
"Prefer create-database in api, schema only in index for attribute reference database."
|
|
823
|
+
([] (empty-db nil nil nil))
|
|
824
|
+
([schema] (empty-db schema nil nil))
|
|
825
|
+
([schema user-config] (empty-db schema user-config nil))
|
|
826
|
+
([schema user-config store]
|
|
827
|
+
{:pre [(or (nil? schema) (map? schema) (coll? schema))]}
|
|
828
|
+
(let [complete-config (merge (dc/storeless-config) user-config)
|
|
829
|
+
_ (dc/validate-config complete-config)
|
|
830
|
+
complete-config (dc/remove-nils complete-config)
|
|
831
|
+
{:keys [keep-history? index schema-flexibility attribute-refs?]} complete-config
|
|
832
|
+
on-read? (= :read schema-flexibility)
|
|
833
|
+
schema (to-old-schema schema)
|
|
834
|
+
_ (if on-read?
|
|
835
|
+
(validate-schema schema)
|
|
836
|
+
(validate-write-schema schema))
|
|
837
|
+
complete-schema (merge schema
|
|
838
|
+
(if attribute-refs?
|
|
839
|
+
c/ref-implicit-schema
|
|
840
|
+
c/non-ref-implicit-schema))
|
|
841
|
+
rschema (dbu/rschema complete-schema)
|
|
842
|
+
ident-ref-map (if attribute-refs? (get-ident-ref-map complete-schema) {})
|
|
843
|
+
ref-ident-map (if attribute-refs? (clojure.set/map-invert ident-ref-map) {})
|
|
844
|
+
system-entities (if attribute-refs? c/system-entities #{})
|
|
845
|
+
indexed (if attribute-refs?
|
|
846
|
+
(set (map ident-ref-map (:db/index rschema)))
|
|
847
|
+
(:db/index rschema))
|
|
848
|
+
index-config (merge (:index-config complete-config)
|
|
849
|
+
{:indexed indexed})
|
|
850
|
+
eavt (if attribute-refs?
|
|
851
|
+
(di/init-index index store ref-datoms :eavt 0 index-config)
|
|
852
|
+
(di/empty-index index store :eavt index-config))
|
|
853
|
+
aevt (if attribute-refs?
|
|
854
|
+
(di/init-index index store ref-datoms :aevt 0 index-config)
|
|
855
|
+
(di/empty-index index store :aevt index-config))
|
|
856
|
+
indexed-datoms (filter (fn [[_ a _ _]] (contains? indexed a)) ref-datoms)
|
|
857
|
+
avet (if attribute-refs?
|
|
858
|
+
(di/init-index index store indexed-datoms :avet 0 index-config)
|
|
859
|
+
(di/empty-index index store :avet index-config))
|
|
860
|
+
max-eid (if attribute-refs? ue0 e0)
|
|
861
|
+
max-tx (if attribute-refs? utx0 tx0)]
|
|
862
|
+
(map->DB
|
|
863
|
+
(merge
|
|
864
|
+
{:schema complete-schema
|
|
865
|
+
:rschema rschema
|
|
866
|
+
:config complete-config
|
|
867
|
+
:eavt eavt
|
|
868
|
+
:aevt aevt
|
|
869
|
+
:avet avet
|
|
870
|
+
:max-eid max-eid
|
|
871
|
+
:max-tx max-tx
|
|
872
|
+
:hash 0
|
|
873
|
+
:system-entities system-entities
|
|
874
|
+
:ref-ident-map ref-ident-map
|
|
875
|
+
:ident-ref-map ident-ref-map
|
|
876
|
+
:meta (meta-data)
|
|
877
|
+
:op-count (if attribute-refs? (count ref-datoms) 0)}
|
|
878
|
+
(when keep-history? ;; no difference for attribute references since no update possible
|
|
879
|
+
{:temporal-eavt eavt
|
|
880
|
+
:temporal-aevt aevt
|
|
881
|
+
:temporal-avet avet}))))))
|
|
882
|
+
|
|
883
|
+
(defn ^DB init-db
|
|
884
|
+
([datoms] (init-db datoms nil nil nil))
|
|
885
|
+
([datoms schema] (init-db datoms schema nil nil))
|
|
886
|
+
([datoms schema user-config] (init-db datoms schema user-config nil))
|
|
887
|
+
([datoms schema user-config store]
|
|
888
|
+
(validate-schema schema)
|
|
889
|
+
(let [{:keys [index keep-history? attribute-refs?] :as complete-config} (merge (dc/storeless-config) user-config)
|
|
890
|
+
_ (dc/validate-config complete-config)
|
|
891
|
+
complete-schema (merge schema
|
|
892
|
+
(if attribute-refs?
|
|
893
|
+
c/ref-implicit-schema
|
|
894
|
+
c/non-ref-implicit-schema))
|
|
895
|
+
rschema (dbu/rschema complete-schema)
|
|
896
|
+
ident-ref-map (if attribute-refs? (get-ident-ref-map schema) {})
|
|
897
|
+
ref-ident-map (if attribute-refs? (clojure.set/map-invert ident-ref-map) {})
|
|
898
|
+
system-entities (if attribute-refs? c/system-entities #{})
|
|
899
|
+
|
|
900
|
+
indexed (if attribute-refs?
|
|
901
|
+
(set (map ident-ref-map (:db/index rschema)))
|
|
902
|
+
(:db/index rschema))
|
|
903
|
+
new-datoms (if attribute-refs? (concat ref-datoms datoms) datoms)
|
|
904
|
+
indexed-datoms (filter (fn [[_ a _ _]] (contains? indexed a)) new-datoms)
|
|
905
|
+
op-count 0
|
|
906
|
+
index-config (assoc (:index-config complete-config)
|
|
907
|
+
:indexed indexed)
|
|
908
|
+
avet (di/init-index index store indexed-datoms :avet op-count index-config)
|
|
909
|
+
eavt (di/init-index index store new-datoms :eavt op-count index-config)
|
|
910
|
+
aevt (di/init-index index store new-datoms :aevt op-count index-config)
|
|
911
|
+
max-eid (init-max-eid eavt)
|
|
912
|
+
max-tx (get-max-tx eavt)
|
|
913
|
+
op-count (count new-datoms)]
|
|
914
|
+
(map->DB (merge {:schema complete-schema
|
|
915
|
+
:rschema rschema
|
|
916
|
+
:config complete-config
|
|
917
|
+
:eavt eavt
|
|
918
|
+
:aevt aevt
|
|
919
|
+
:avet avet
|
|
920
|
+
:max-eid max-eid
|
|
921
|
+
:max-tx max-tx
|
|
922
|
+
:op-count op-count
|
|
923
|
+
:hash (reduce #(+ %1 (hash %2)) 0 datoms)
|
|
924
|
+
:system-entities system-entities
|
|
925
|
+
:meta (meta-data)
|
|
926
|
+
:ref-ident-map ref-ident-map
|
|
927
|
+
:ident-ref-map ident-ref-map}
|
|
928
|
+
(when keep-history?
|
|
929
|
+
{:temporal-eavt (di/empty-index index store :eavt index-config)
|
|
930
|
+
:temporal-aevt (di/empty-index index store :aevt index-config)
|
|
931
|
+
:temporal-avet (di/empty-index index store :avet index-config)}))))))
|
|
932
|
+
|
|
933
|
+
(defn metrics [^DB db]
|
|
934
|
+
(let [update-count-in (fn [m ks] (update-in m ks #(if % (inc %) 1)))
|
|
935
|
+
counts-map (->> (di/-seq (.-eavt db))
|
|
936
|
+
(reduce (fn [m ^Datom datom]
|
|
937
|
+
(-> m
|
|
938
|
+
(update-count-in [:per-attr-counts (dbi/-ident-for db (.-a datom))])
|
|
939
|
+
(update-count-in [:per-entity-counts (.-e datom)])))
|
|
940
|
+
{:per-attr-counts {}
|
|
941
|
+
:per-entity-counts {}}))
|
|
942
|
+
sum-indexed-attr-counts (fn [attr-counts] (->> attr-counts
|
|
943
|
+
(m/filter-keys #(contains? (:db/index (.-rschema db)) %))
|
|
944
|
+
vals
|
|
945
|
+
(reduce + 0)))]
|
|
946
|
+
(cond-> (merge counts-map
|
|
947
|
+
{:count (di/-count (.-eavt db))
|
|
948
|
+
:avet-count (->> (:per-attr-counts counts-map)
|
|
949
|
+
sum-indexed-attr-counts)})
|
|
950
|
+
(dbi/-keep-history? db)
|
|
951
|
+
(merge {:temporal-count (di/-count (.-temporal-eavt db))
|
|
952
|
+
:temporal-avet-count (->> (di/-seq (.-temporal-eavt db))
|
|
953
|
+
(reduce (fn [m ^Datom datom] (update-count-in m [(dbi/-ident-for db (.-a datom))]))
|
|
954
|
+
{})
|
|
955
|
+
sum-indexed-attr-counts)}))))
|
|
956
|
+
|