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,363 @@
|
|
|
1
|
+
# Storage Backends
|
|
2
|
+
|
|
3
|
+
Datahike provides pluggable storage through [konserve](https://github.com/replikativ/konserve), allowing you to choose the backend that best fits your deployment model and performance requirements.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Backend | Best For | Distribution | Durability | Write Throughput |
|
|
8
|
+
|---------|----------|--------------|------------|------------------|
|
|
9
|
+
| **File** | Unix tools, rsync, git-like workflows | Single machine | High | Good |
|
|
10
|
+
| **LMDB** | High-performance single machine | Single filesystem | High | Excellent |
|
|
11
|
+
| **Memory** | Testing, ephemeral data | Single process | None | Excellent |
|
|
12
|
+
| **JDBC** | Existing SQL infrastructure | Multi-machine | High | Good |
|
|
13
|
+
| **Redis** | High write throughput | Multi-machine | Medium | Excellent |
|
|
14
|
+
| **S3** | Distributed scale-out, cost-effective | Multi-region | Very high | Good |
|
|
15
|
+
| **GCS** | Google Cloud scale-out | Multi-region | Very high | Good |
|
|
16
|
+
| **DynamoDB** | Low latency, AWS-native | Multi-region | Very high | Excellent (expensive) |
|
|
17
|
+
| **IndexedDB** | Browser persistence | Browser | Medium | Good |
|
|
18
|
+
|
|
19
|
+
## Local Backends
|
|
20
|
+
|
|
21
|
+
### File Backend
|
|
22
|
+
|
|
23
|
+
**Use when**: You want to use Unix tools (rsync, git, backup scripts) to manage your database.
|
|
24
|
+
|
|
25
|
+
**Key advantage**: Deltas in persistent data structures translate directly into individual file deltas, making incremental backups and synchronization highly efficient.
|
|
26
|
+
|
|
27
|
+
```clojure
|
|
28
|
+
{:store {:backend :file
|
|
29
|
+
:path "/var/lib/myapp/db"}}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Characteristics**:
|
|
33
|
+
- Each immutable index fragment stored as an individual file
|
|
34
|
+
- Efficient incremental backups with rsync
|
|
35
|
+
- Can version database directories similar to or with git
|
|
36
|
+
- Good for single-machine deployments
|
|
37
|
+
- Extensively tested and reliable without external dependencies
|
|
38
|
+
- Not ideal for databases with a lot of churn
|
|
39
|
+
|
|
40
|
+
### LMDB Backend
|
|
41
|
+
|
|
42
|
+
**Use when**: You need maximum performance on a single machine within a single filesystem.
|
|
43
|
+
|
|
44
|
+
**Key advantage**: Lightning-fast memory-mapped database with ACID transactions, optimized for read-heavy workloads.
|
|
45
|
+
|
|
46
|
+
```clojure
|
|
47
|
+
;; Requires: org.replikativ/datahike-lmdb
|
|
48
|
+
{:store {:backend :lmdb
|
|
49
|
+
:path "/var/lib/myapp/db"}}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Characteristics**:
|
|
53
|
+
- Memory-mapped for zero-copy reads
|
|
54
|
+
- Single filesystem only (not distributed)
|
|
55
|
+
- Excellent read performance
|
|
56
|
+
- Lower memory overhead than file backend
|
|
57
|
+
- Well suited for very high churn of small changes
|
|
58
|
+
- Very low latency
|
|
59
|
+
- Large file blob that cannot be as efficiently synched a the file store
|
|
60
|
+
|
|
61
|
+
**Note**: The LMDB backend is available as a separate library: [datahike-lmdb](https://github.com/replikativ/datahike-lmdb), extending [konserve-lmdb](https://github.com/replikativ/lmdb).
|
|
62
|
+
|
|
63
|
+
### Memory Backend
|
|
64
|
+
|
|
65
|
+
**Use when**: Testing, development, or ephemeral data that doesn't need to survive process restarts.
|
|
66
|
+
|
|
67
|
+
```clojure
|
|
68
|
+
{:store {:backend :memory
|
|
69
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440030"}}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Characteristics**:
|
|
73
|
+
- No persistence - data lost on process exit
|
|
74
|
+
- Fastest possible performance
|
|
75
|
+
- Ideal for unit tests and REPL development
|
|
76
|
+
- Multiple databases distinguished by `:id`
|
|
77
|
+
|
|
78
|
+
## Distributed Backends
|
|
79
|
+
|
|
80
|
+
All distributed backends support **Distributed Index Space (DIS)**: multiple reader processes can directly access shared storage without database connections, enabling massive read scalability.
|
|
81
|
+
|
|
82
|
+
**Important**: Datahike uses a single-writer model. Multiple readers can access indices concurrently, but only one writer process should transact at a time. This is the same model used by Datomic, Datalevin, and XTDB.
|
|
83
|
+
|
|
84
|
+
### JDBC Backend
|
|
85
|
+
|
|
86
|
+
**Use when**: You already have PostgreSQL or another JDBC database in your infrastructure.
|
|
87
|
+
|
|
88
|
+
**Key advantage**: Leverage existing SQL database skills, backup procedures, and monitoring tools.
|
|
89
|
+
|
|
90
|
+
```clojure
|
|
91
|
+
;; Requires: org.replikativ/datahike-jdbc
|
|
92
|
+
{:store {:backend :jdbc
|
|
93
|
+
:dbtype "postgresql"
|
|
94
|
+
:host "db.example.com"
|
|
95
|
+
:port 5432
|
|
96
|
+
:dbname "datahike"
|
|
97
|
+
:user "datahike"
|
|
98
|
+
:password "..."}}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Characteristics**:
|
|
102
|
+
- Use familiar SQL database operations
|
|
103
|
+
- Existing backup/restore procedures work
|
|
104
|
+
- Read scaling via DIS (readers don't interfere with writer in database's MVCC)
|
|
105
|
+
- Good for teams already operating PostgreSQL
|
|
106
|
+
- Available for: PostgreSQL, MySQL, H2, and others
|
|
107
|
+
|
|
108
|
+
**Note**: Available as separate library: [datahike-jdbc](https://github.com/replikativ/datahike-jdbc)
|
|
109
|
+
|
|
110
|
+
### Redis Backend
|
|
111
|
+
|
|
112
|
+
**Use when**: You need high write throughput and can tolerate weaker durability guarantees.
|
|
113
|
+
|
|
114
|
+
**Key advantage**: Excellent write performance with in-memory speed.
|
|
115
|
+
|
|
116
|
+
```clojure
|
|
117
|
+
;; Requires: org.replikativ/konserve-redis
|
|
118
|
+
{:store {:backend :redis
|
|
119
|
+
:host "redis.example.com"
|
|
120
|
+
:port 6379}}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Characteristics**:
|
|
124
|
+
- Very high write throughput
|
|
125
|
+
- Durability depends on Redis persistence settings (RDB/AOF)
|
|
126
|
+
- Can lose recent writes on Redis crash
|
|
127
|
+
- Good for high-traffic applications where some data loss is acceptable
|
|
128
|
+
- Distributed reads via DIS
|
|
129
|
+
|
|
130
|
+
### S3 Backend
|
|
131
|
+
|
|
132
|
+
**Use when**: You want cost-effective distributed storage that scales to massive datasets.
|
|
133
|
+
|
|
134
|
+
**Key advantage**: Extremely scalable, pay-per-use pricing, natural fit for cloud-native architectures.
|
|
135
|
+
|
|
136
|
+
```clojure
|
|
137
|
+
;; Requires: org.replikativ/konserve-s3
|
|
138
|
+
{:store {:backend :s3
|
|
139
|
+
:bucket "my-datahike-bucket"
|
|
140
|
+
:region "us-east-1"}}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Characteristics**:
|
|
144
|
+
- Unlimited scalability
|
|
145
|
+
- Very low storage costs (compared to databases)
|
|
146
|
+
- High durability (11 nines)
|
|
147
|
+
- Eventually consistent (may have slight read lag)
|
|
148
|
+
- Ideal for read-heavy workloads with occasional writes
|
|
149
|
+
- Can have high latency
|
|
150
|
+
- Works well with AWS Lambda deployments
|
|
151
|
+
|
|
152
|
+
**Performance note**: Higher latency than local storage, but cost-effective for billions of datoms.
|
|
153
|
+
|
|
154
|
+
### Google Cloud Storage (GCS) Backend
|
|
155
|
+
|
|
156
|
+
**Use when**: You're on Google Cloud Platform and want distributed storage.
|
|
157
|
+
|
|
158
|
+
**Key advantage**: Similar to S3 but optimized for GCP infrastructure.
|
|
159
|
+
|
|
160
|
+
```clojure
|
|
161
|
+
;; Requires: org.replikativ/konserve-gcs
|
|
162
|
+
{:store {:backend :gcs
|
|
163
|
+
:bucket "my-datahike-bucket"
|
|
164
|
+
:project-id "my-project"}}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Characteristics**:
|
|
168
|
+
- Similar to S3 in characteristics
|
|
169
|
+
- Native GCP integration
|
|
170
|
+
- Good latency within GCP regions
|
|
171
|
+
- Cost-effective for large datasets
|
|
172
|
+
|
|
173
|
+
### DynamoDB Backend
|
|
174
|
+
|
|
175
|
+
**Use when**: You need low-latency distributed storage and are willing to pay premium pricing.
|
|
176
|
+
|
|
177
|
+
**Key advantage**: Single-digit millisecond latency with strong consistency options.
|
|
178
|
+
|
|
179
|
+
```clojure
|
|
180
|
+
;; Requires: org.replikativ/konserve-dynamodb
|
|
181
|
+
{:store {:backend :dynamodb
|
|
182
|
+
:table "datahike"
|
|
183
|
+
:region "us-east-1"}}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Characteristics**:
|
|
187
|
+
- Very low latency
|
|
188
|
+
- Strong consistency available
|
|
189
|
+
- Higher costs than S3
|
|
190
|
+
- Good for latency-sensitive applications
|
|
191
|
+
- On-demand or provisioned capacity modes
|
|
192
|
+
|
|
193
|
+
## Browser Backend
|
|
194
|
+
|
|
195
|
+
### IndexedDB Backend
|
|
196
|
+
|
|
197
|
+
**Use when**: Building offline-capable browser applications with persistent local storage.
|
|
198
|
+
|
|
199
|
+
**Key advantage**: Durable browser-local storage with ClojureScript support.
|
|
200
|
+
|
|
201
|
+
```clojure
|
|
202
|
+
;; ClojureScript only
|
|
203
|
+
{:store {:backend :indexeddb
|
|
204
|
+
:id "my-app-db"}}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Characteristics**:
|
|
208
|
+
- Persistent across browser sessions
|
|
209
|
+
- ~50MB-unlimited quota (browser-dependent)
|
|
210
|
+
- Asynchronous API
|
|
211
|
+
- Often paired with TieredStore for performance
|
|
212
|
+
|
|
213
|
+
## Advanced: TieredStore
|
|
214
|
+
|
|
215
|
+
**TieredStore** creates memory hierarchies by layering backends, with faster storage in front of slower, more durable storage.
|
|
216
|
+
|
|
217
|
+
**Use cases**:
|
|
218
|
+
- **Browser**: Memory (fast) → IndexedDB (persistent)
|
|
219
|
+
- **Server**: Memory → LMDB → S3 (hot → warm → cold)
|
|
220
|
+
- **AWS**: LMDB (fast local) → S3 (distributed backup)
|
|
221
|
+
|
|
222
|
+
```clojure
|
|
223
|
+
;; Example: Fast memory cache backed by S3
|
|
224
|
+
{:store {:backend :tiered
|
|
225
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440031"
|
|
226
|
+
:frontend-config {:backend :memory
|
|
227
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440031"}
|
|
228
|
+
:backend-config {:backend :s3
|
|
229
|
+
:bucket "persistent-store"
|
|
230
|
+
:region "us-east-1"
|
|
231
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440031"}
|
|
232
|
+
:write-policy :write-through
|
|
233
|
+
:read-policy :frontend-first}}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**How it works**:
|
|
237
|
+
- Reads check tiers in order (cache-first)
|
|
238
|
+
- Writes go to all tiers
|
|
239
|
+
- Stacking multiple tiers supported but rarely needed
|
|
240
|
+
- Provided by konserve's tiered store implementation
|
|
241
|
+
|
|
242
|
+
**Common patterns**:
|
|
243
|
+
|
|
244
|
+
**Browser with offline support**:
|
|
245
|
+
```clojure
|
|
246
|
+
{:store {:backend :tiered
|
|
247
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440032"
|
|
248
|
+
:frontend-config {:backend :memory
|
|
249
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440032"}
|
|
250
|
+
:backend-config {:backend :indexeddb
|
|
251
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440032"}
|
|
252
|
+
:write-policy :write-through}}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**AWS Lambda with S3 backing**:
|
|
256
|
+
```clojure
|
|
257
|
+
{:store {:backend :tiered
|
|
258
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440033"
|
|
259
|
+
:frontend-config {:backend :lmdb
|
|
260
|
+
:path "/tmp/cache"
|
|
261
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440033"}
|
|
262
|
+
:backend-config {:backend :s3
|
|
263
|
+
:bucket "lambda-data"
|
|
264
|
+
:region "us-east-1"
|
|
265
|
+
:id #uuid "550e8400-e29b-41d4-a716-446655440033"}}}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Backend-Specific Configuration
|
|
269
|
+
|
|
270
|
+
Each backend may have additional configuration options. See the konserve backend documentation for details:
|
|
271
|
+
|
|
272
|
+
- [konserve](https://github.com/replikativ/konserve) - Core abstraction
|
|
273
|
+
- [konserve-lmdb](https://github.com/replikativ/lmdb) - LMDB implementation
|
|
274
|
+
- [datahike-lmdb](https://github.com/replikativ/datahike-lmdb) - Datahike LMDB integration
|
|
275
|
+
- [datahike-jdbc](https://github.com/replikativ/datahike-jdbc) - JDBC backends
|
|
276
|
+
- [konserve-s3](https://github.com/replikativ/konserve-s3) - S3 backend
|
|
277
|
+
- [konserve-redis](https://github.com/replikativ/konserve-redis) - Redis backend
|
|
278
|
+
|
|
279
|
+
## Choosing a Backend
|
|
280
|
+
|
|
281
|
+
### For Development
|
|
282
|
+
→ **Memory** or **File** backend for simplicity
|
|
283
|
+
|
|
284
|
+
### For Single-Machine Production
|
|
285
|
+
→ **LMDB** for best performance
|
|
286
|
+
→ **File** if you need Unix tool integration
|
|
287
|
+
|
|
288
|
+
### For Distributed Production (Read Scaling)
|
|
289
|
+
→ **S3/GCS** for cost-effective scale
|
|
290
|
+
→ **DynamoDB** for low latency (higher cost)
|
|
291
|
+
→ **JDBC** if you already operate PostgreSQL
|
|
292
|
+
|
|
293
|
+
### For High Write Throughput
|
|
294
|
+
→ **Redis** if you can tolerate some data loss
|
|
295
|
+
→ **LMDB** for durable local writes
|
|
296
|
+
→ **DynamoDB** for distributed writes (expensive)
|
|
297
|
+
|
|
298
|
+
### For Browser Applications
|
|
299
|
+
→ **IndexedDB** for persistence
|
|
300
|
+
→ **TieredStore** (Memory → IndexedDB) for speed + durability
|
|
301
|
+
|
|
302
|
+
### For Cost Optimization
|
|
303
|
+
→ **File** backend with rsync for cheap backups
|
|
304
|
+
→ **S3** for large datasets (pennies per GB)
|
|
305
|
+
→ **TieredStore** to minimize expensive tier access
|
|
306
|
+
|
|
307
|
+
## Migration Between Backends
|
|
308
|
+
|
|
309
|
+
To migrate from one backend to another:
|
|
310
|
+
|
|
311
|
+
1. Export from source database:
|
|
312
|
+
```clojure
|
|
313
|
+
(require '[datahike.migrate :refer [export-db import-db]])
|
|
314
|
+
(export-db source-conn "/tmp/datoms-export")
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
2. Create destination database with new backend:
|
|
318
|
+
```clojure
|
|
319
|
+
(d/create-database new-config)
|
|
320
|
+
(def dest-conn (d/connect new-config))
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
3. Import into destination:
|
|
324
|
+
```clojure
|
|
325
|
+
(import-db dest-conn "/tmp/datoms-export")
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
The export format (CBOR) preserves all data types including binary data.
|
|
329
|
+
|
|
330
|
+
## Performance Considerations
|
|
331
|
+
|
|
332
|
+
### Read Performance
|
|
333
|
+
- **Fastest**: Memory, LMDB (memory-mapped)
|
|
334
|
+
- **Fast**: File (SSD), Redis
|
|
335
|
+
- **Good**: JDBC, S3 (with tiering)
|
|
336
|
+
- **Variable**: DynamoDB (provisioned vs on-demand)
|
|
337
|
+
|
|
338
|
+
### Write Performance
|
|
339
|
+
- **Fastest**: Memory, Redis
|
|
340
|
+
- **Fast**: LMDB, DynamoDB (provisioned)
|
|
341
|
+
- **Good**: File, JDBC, S3
|
|
342
|
+
- **Slower**: S3 (especially small writes)
|
|
343
|
+
|
|
344
|
+
### Distribution
|
|
345
|
+
- **No distribution**: Memory, File, LMDB (single filesystem)
|
|
346
|
+
- **Distributed reads**: All cloud backends via DIS
|
|
347
|
+
- **Single writer**: All backends (architectural constraint)
|
|
348
|
+
|
|
349
|
+
### Durability
|
|
350
|
+
- **None**: Memory (ephemeral)
|
|
351
|
+
- **Medium**: Redis (depends on persistence settings), IndexedDB
|
|
352
|
+
- **High**: File, LMDB, JDBC
|
|
353
|
+
- **Very high**: S3, GCS, DynamoDB (11 nines)
|
|
354
|
+
|
|
355
|
+
## Custom Backends
|
|
356
|
+
|
|
357
|
+
Datahike can use any konserve backend. To create a custom backend:
|
|
358
|
+
|
|
359
|
+
1. Implement the [konserve protocols](https://github.com/replikativ/konserve/blob/main/src/konserve/protocols.cljc)
|
|
360
|
+
2. Register your backend with konserve
|
|
361
|
+
3. Use it in Datahike configuration
|
|
362
|
+
|
|
363
|
+
See the [konserve documentation](https://github.com/replikativ/konserve) for details on implementing custom backends.
|