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.
Files changed (324) hide show
  1. package/.circleci/config.yml +405 -0
  2. package/.circleci/scripts/gen_ci.clj +194 -0
  3. package/.cirrus.yml +60 -0
  4. package/.clj-kondo/babashka/sci/config.edn +1 -0
  5. package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
  6. package/.clj-kondo/config.edn +95 -0
  7. package/.dir-locals.el +2 -0
  8. package/.github/FUNDING.yml +3 -0
  9. package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
  10. package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
  11. package/.github/ISSUE_TEMPLATE/config.yml +6 -0
  12. package/.github/pull_request_template.md +24 -0
  13. package/.github/workflows/native-image.yml +84 -0
  14. package/LICENSE +203 -0
  15. package/README.md +273 -0
  16. package/bb/deps.edn +9 -0
  17. package/bb/resources/github-fingerprints +3 -0
  18. package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
  19. package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
  20. package/bb/resources/native-image-tests/run-native-image-tests +74 -0
  21. package/bb/resources/native-image-tests/run-python-tests +22 -0
  22. package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
  23. package/bb/resources/native-image-tests/testconfig.edn +5 -0
  24. package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
  25. package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
  26. package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
  27. package/bb/resources/template/pom.xml +22 -0
  28. package/bb/src/tools/build.clj +132 -0
  29. package/bb/src/tools/clj_kondo.clj +32 -0
  30. package/bb/src/tools/deploy.clj +26 -0
  31. package/bb/src/tools/examples.clj +19 -0
  32. package/bb/src/tools/npm.clj +100 -0
  33. package/bb/src/tools/python.clj +14 -0
  34. package/bb/src/tools/release.clj +94 -0
  35. package/bb/src/tools/test.clj +148 -0
  36. package/bb/src/tools/version.clj +47 -0
  37. package/bb.edn +269 -0
  38. package/benchmark/src/benchmark/cli.clj +195 -0
  39. package/benchmark/src/benchmark/compare.clj +157 -0
  40. package/benchmark/src/benchmark/config.clj +316 -0
  41. package/benchmark/src/benchmark/measure.clj +187 -0
  42. package/benchmark/src/benchmark/store.clj +190 -0
  43. package/benchmark/test/benchmark/measure_test.clj +156 -0
  44. package/build.clj +30 -0
  45. package/config.edn +49 -0
  46. package/deps.edn +138 -0
  47. package/dev/sandbox.clj +82 -0
  48. package/dev/sandbox.cljs +127 -0
  49. package/dev/sandbox_benchmarks.clj +27 -0
  50. package/dev/sandbox_client.clj +87 -0
  51. package/dev/sandbox_transact_bench.clj +109 -0
  52. package/dev/user.clj +79 -0
  53. package/doc/README.md +96 -0
  54. package/doc/adl/README.md +6 -0
  55. package/doc/adl/adr-000-adr.org +28 -0
  56. package/doc/adl/adr-001-attribute-references.org +15 -0
  57. package/doc/adl/adr-002-build-tooling.org +54 -0
  58. package/doc/adl/adr-003-db-meta-data.md +52 -0
  59. package/doc/adl/adr-004-github-flow.md +40 -0
  60. package/doc/adl/adr-XYZ-template.md +30 -0
  61. package/doc/adl/index.org +3 -0
  62. package/doc/assets/datahike-logo.svg +3 -0
  63. package/doc/assets/datahiking-invoice.org +85 -0
  64. package/doc/assets/hhtree2.png +0 -0
  65. package/doc/assets/network_topology.svg +624 -0
  66. package/doc/assets/perf.png +0 -0
  67. package/doc/assets/schema_mindmap.mm +132 -0
  68. package/doc/assets/schema_mindmap.svg +970 -0
  69. package/doc/assets/temporal_index.mm +74 -0
  70. package/doc/backend-development.md +78 -0
  71. package/doc/bb-pod.md +89 -0
  72. package/doc/benchmarking.md +360 -0
  73. package/doc/bindings/edn-conversion.md +383 -0
  74. package/doc/cli.md +162 -0
  75. package/doc/cljdoc.edn +27 -0
  76. package/doc/cljs-support.md +133 -0
  77. package/doc/config.md +406 -0
  78. package/doc/contributing.md +114 -0
  79. package/doc/datalog-vs-sql.md +210 -0
  80. package/doc/datomic_differences.md +109 -0
  81. package/doc/development/pull-api-ns.md +186 -0
  82. package/doc/development/pull-frame-state-diagram.jpg +0 -0
  83. package/doc/distributed.md +566 -0
  84. package/doc/entity_spec.md +92 -0
  85. package/doc/gc.md +273 -0
  86. package/doc/java-api.md +808 -0
  87. package/doc/javascript-api.md +421 -0
  88. package/doc/libdatahike.md +86 -0
  89. package/doc/logging_and_error_handling.md +43 -0
  90. package/doc/norms.md +66 -0
  91. package/doc/schema-migration.md +85 -0
  92. package/doc/schema.md +287 -0
  93. package/doc/storage-backends.md +363 -0
  94. package/doc/store-id-refactoring.md +596 -0
  95. package/doc/time_variance.md +325 -0
  96. package/doc/unstructured.md +167 -0
  97. package/doc/versioning.md +261 -0
  98. package/examples/basic/README.md +19 -0
  99. package/examples/basic/deps.edn +6 -0
  100. package/examples/basic/docker-compose.yml +13 -0
  101. package/examples/basic/src/examples/core.clj +60 -0
  102. package/examples/basic/src/examples/schema.clj +155 -0
  103. package/examples/basic/src/examples/store.clj +60 -0
  104. package/examples/basic/src/examples/time_travel.clj +185 -0
  105. package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
  106. package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
  107. package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
  108. package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
  109. package/examples/java/README.md +162 -0
  110. package/examples/java/pom.xml +62 -0
  111. package/examples/java/src/main/java/examples/QuickStart.java +115 -0
  112. package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
  113. package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
  114. package/flake.lock +27 -0
  115. package/flake.nix +27 -0
  116. package/http-server/datahike/http/middleware.clj +75 -0
  117. package/http-server/datahike/http/server.clj +269 -0
  118. package/java/src/datahike/java/Database.java +274 -0
  119. package/java/src/datahike/java/Datahike.java +281 -0
  120. package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
  121. package/java/src/datahike/java/DatahikeTest.java +370 -0
  122. package/java/src/datahike/java/EDN.java +170 -0
  123. package/java/src/datahike/java/IEntity.java +11 -0
  124. package/java/src/datahike/java/Keywords.java +161 -0
  125. package/java/src/datahike/java/SchemaFlexibility.java +52 -0
  126. package/java/src/datahike/java/Util.java +219 -0
  127. package/karma.conf.js +19 -0
  128. package/libdatahike/compile-cpp +7 -0
  129. package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
  130. package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
  131. package/libdatahike/src/test_cpp.cpp +61 -0
  132. package/npm-package/PUBLISHING.md +140 -0
  133. package/npm-package/README.md +226 -0
  134. package/npm-package/package.template.json +34 -0
  135. package/npm-package/test-isomorphic.ts +281 -0
  136. package/npm-package/test.js +557 -0
  137. package/npm-package/typescript-test.ts +70 -0
  138. package/package.json +16 -0
  139. package/pydatahike/README.md +569 -0
  140. package/pydatahike/pyproject.toml +91 -0
  141. package/pydatahike/setup.py +42 -0
  142. package/pydatahike/src/datahike/__init__.py +134 -0
  143. package/pydatahike/src/datahike/_native.py +250 -0
  144. package/pydatahike/src/datahike/_version.py +2 -0
  145. package/pydatahike/src/datahike/database.py +722 -0
  146. package/pydatahike/src/datahike/edn.py +311 -0
  147. package/pydatahike/src/datahike/py.typed +0 -0
  148. package/pydatahike/tests/conftest.py +17 -0
  149. package/pydatahike/tests/test_basic.py +170 -0
  150. package/pydatahike/tests/test_database.py +51 -0
  151. package/pydatahike/tests/test_edn_conversion.py +299 -0
  152. package/pydatahike/tests/test_query.py +99 -0
  153. package/pydatahike/tests/test_schema.py +55 -0
  154. package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
  155. package/resources/example_server.edn +4 -0
  156. package/shadow-cljs.edn +56 -0
  157. package/src/data_readers.clj +7 -0
  158. package/src/datahike/api/impl.cljc +176 -0
  159. package/src/datahike/api/specification.cljc +633 -0
  160. package/src/datahike/api/types.cljc +261 -0
  161. package/src/datahike/api.cljc +41 -0
  162. package/src/datahike/array.cljc +99 -0
  163. package/src/datahike/cli.clj +166 -0
  164. package/src/datahike/cljs.cljs +6 -0
  165. package/src/datahike/codegen/cli.clj +406 -0
  166. package/src/datahike/codegen/clj_kondo.clj +291 -0
  167. package/src/datahike/codegen/java.clj +403 -0
  168. package/src/datahike/codegen/naming.cljc +33 -0
  169. package/src/datahike/codegen/native.clj +559 -0
  170. package/src/datahike/codegen/pod.clj +488 -0
  171. package/src/datahike/codegen/python.clj +838 -0
  172. package/src/datahike/codegen/report.clj +55 -0
  173. package/src/datahike/codegen/typescript.clj +262 -0
  174. package/src/datahike/codegen/validation.clj +145 -0
  175. package/src/datahike/config.cljc +294 -0
  176. package/src/datahike/connections.cljc +16 -0
  177. package/src/datahike/connector.cljc +265 -0
  178. package/src/datahike/constants.cljc +142 -0
  179. package/src/datahike/core.cljc +297 -0
  180. package/src/datahike/datom.cljc +459 -0
  181. package/src/datahike/db/interface.cljc +119 -0
  182. package/src/datahike/db/search.cljc +305 -0
  183. package/src/datahike/db/transaction.cljc +937 -0
  184. package/src/datahike/db/utils.cljc +338 -0
  185. package/src/datahike/db.cljc +956 -0
  186. package/src/datahike/experimental/unstructured.cljc +126 -0
  187. package/src/datahike/experimental/versioning.cljc +172 -0
  188. package/src/datahike/externs.js +31 -0
  189. package/src/datahike/gc.cljc +69 -0
  190. package/src/datahike/http/client.clj +188 -0
  191. package/src/datahike/http/writer.clj +79 -0
  192. package/src/datahike/impl/entity.cljc +218 -0
  193. package/src/datahike/index/interface.cljc +93 -0
  194. package/src/datahike/index/persistent_set.cljc +469 -0
  195. package/src/datahike/index/utils.cljc +44 -0
  196. package/src/datahike/index.cljc +32 -0
  197. package/src/datahike/js/api.cljs +172 -0
  198. package/src/datahike/js/api_macros.clj +22 -0
  199. package/src/datahike/js.cljs +163 -0
  200. package/src/datahike/json.cljc +209 -0
  201. package/src/datahike/lru.cljc +146 -0
  202. package/src/datahike/migrate.clj +39 -0
  203. package/src/datahike/norm/norm.clj +245 -0
  204. package/src/datahike/online_gc.cljc +252 -0
  205. package/src/datahike/pod.clj +155 -0
  206. package/src/datahike/pull_api.cljc +325 -0
  207. package/src/datahike/query.cljc +1945 -0
  208. package/src/datahike/query_stats.cljc +88 -0
  209. package/src/datahike/readers.cljc +62 -0
  210. package/src/datahike/remote.cljc +218 -0
  211. package/src/datahike/schema.cljc +228 -0
  212. package/src/datahike/schema_cache.cljc +42 -0
  213. package/src/datahike/spec.cljc +101 -0
  214. package/src/datahike/store.cljc +80 -0
  215. package/src/datahike/tools.cljc +308 -0
  216. package/src/datahike/transit.cljc +80 -0
  217. package/src/datahike/writer.cljc +239 -0
  218. package/src/datahike/writing.cljc +362 -0
  219. package/src/deps.cljs +1 -0
  220. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
  221. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
  222. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
  223. package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
  224. package/test/datahike/integration_test/config_record_file_test.clj +14 -0
  225. package/test/datahike/integration_test/config_record_test.clj +14 -0
  226. package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
  227. package/test/datahike/integration_test/return_map_test.clj +62 -0
  228. package/test/datahike/integration_test.cljc +67 -0
  229. package/test/datahike/norm/norm_test.clj +124 -0
  230. package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
  231. package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
  232. package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
  233. package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
  234. package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
  235. package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
  236. package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
  237. package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
  238. package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
  239. package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
  240. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
  241. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
  242. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
  243. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
  244. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
  245. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
  246. package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
  247. package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
  248. package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
  249. package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
  250. package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
  251. package/test/datahike/test/api_test.cljc +895 -0
  252. package/test/datahike/test/array_test.cljc +40 -0
  253. package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
  254. package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
  255. package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
  256. package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
  257. package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
  258. package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
  259. package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
  260. package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
  261. package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
  262. package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
  263. package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
  264. package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
  265. package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
  266. package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
  267. package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
  268. package/test/datahike/test/attribute_refs/utils.cljc +128 -0
  269. package/test/datahike/test/cache_test.cljc +38 -0
  270. package/test/datahike/test/components_test.cljc +92 -0
  271. package/test/datahike/test/config_test.cljc +158 -0
  272. package/test/datahike/test/core_test.cljc +105 -0
  273. package/test/datahike/test/datom_test.cljc +44 -0
  274. package/test/datahike/test/db_test.cljc +54 -0
  275. package/test/datahike/test/entity_spec_test.cljc +159 -0
  276. package/test/datahike/test/entity_test.cljc +103 -0
  277. package/test/datahike/test/explode_test.cljc +143 -0
  278. package/test/datahike/test/filter_test.cljc +75 -0
  279. package/test/datahike/test/gc_test.cljc +159 -0
  280. package/test/datahike/test/http/server_test.clj +192 -0
  281. package/test/datahike/test/http/writer_test.clj +86 -0
  282. package/test/datahike/test/ident_test.cljc +32 -0
  283. package/test/datahike/test/index_test.cljc +345 -0
  284. package/test/datahike/test/insert.cljc +125 -0
  285. package/test/datahike/test/java_bindings_test.clj +6 -0
  286. package/test/datahike/test/listen_test.cljc +41 -0
  287. package/test/datahike/test/lookup_refs_test.cljc +266 -0
  288. package/test/datahike/test/lru_test.cljc +27 -0
  289. package/test/datahike/test/migrate_test.clj +297 -0
  290. package/test/datahike/test/model/core.cljc +376 -0
  291. package/test/datahike/test/model/invariant.cljc +142 -0
  292. package/test/datahike/test/model/rng.cljc +82 -0
  293. package/test/datahike/test/model_test.clj +217 -0
  294. package/test/datahike/test/nodejs_test.cljs +262 -0
  295. package/test/datahike/test/online_gc_test.cljc +475 -0
  296. package/test/datahike/test/pod_test.clj +369 -0
  297. package/test/datahike/test/pull_api_test.cljc +474 -0
  298. package/test/datahike/test/purge_test.cljc +144 -0
  299. package/test/datahike/test/query_aggregates_test.cljc +101 -0
  300. package/test/datahike/test/query_find_specs_test.cljc +52 -0
  301. package/test/datahike/test/query_fns_test.cljc +523 -0
  302. package/test/datahike/test/query_interop_test.cljc +47 -0
  303. package/test/datahike/test/query_not_test.cljc +189 -0
  304. package/test/datahike/test/query_or_test.cljc +158 -0
  305. package/test/datahike/test/query_pull_test.cljc +147 -0
  306. package/test/datahike/test/query_rules_test.cljc +248 -0
  307. package/test/datahike/test/query_stats_test.cljc +218 -0
  308. package/test/datahike/test/query_test.cljc +984 -0
  309. package/test/datahike/test/schema_test.cljc +424 -0
  310. package/test/datahike/test/specification_test.cljc +30 -0
  311. package/test/datahike/test/store_test.cljc +78 -0
  312. package/test/datahike/test/stress_test.cljc +57 -0
  313. package/test/datahike/test/time_variance_test.cljc +518 -0
  314. package/test/datahike/test/tools_test.clj +134 -0
  315. package/test/datahike/test/transact_test.cljc +518 -0
  316. package/test/datahike/test/tuples_test.cljc +564 -0
  317. package/test/datahike/test/unstructured_test.cljc +291 -0
  318. package/test/datahike/test/upsert_impl_test.cljc +205 -0
  319. package/test/datahike/test/upsert_test.cljc +363 -0
  320. package/test/datahike/test/utils.cljc +110 -0
  321. package/test/datahike/test/validation_test.cljc +48 -0
  322. package/test/datahike/test/versioning_test.cljc +56 -0
  323. package/test/datahike/test.cljc +66 -0
  324. package/tests.edn +24 -0
@@ -0,0 +1,459 @@
1
+ (ns ^:no-doc datahike.datom
2
+ (:require [clojure.walk]
3
+ [clojure.data]
4
+ [datahike.constants :refer [tx0]]
5
+ [datahike.tools :refer [combine-hashes]]
6
+ #?(:cljs [goog.array :as garray]))
7
+ #?(:cljs (:require-macros [datahike.datom :refer [combine-cmp]])))
8
+
9
+ (declare hash-datom equiv-datom seq-datom nth-datom assoc-datom val-at-datom)
10
+
11
+ (defprotocol IDatom
12
+ (datom-tx [this])
13
+ (datom-added [this]))
14
+
15
+ (deftype Datom #?(:clj [^long e a v ^long tx ^:unsynchronized-mutable ^int _hash]
16
+ :cljs [^number e a v ^number tx ^:mutable ^number _hash])
17
+ IDatom
18
+ (datom-tx [d] (if (pos? tx) tx (- tx)))
19
+ (datom-added [d] (pos? tx))
20
+
21
+ #?@(:cljs
22
+ [IHash
23
+ (-hash [d] (if (zero? _hash)
24
+ (set! _hash (hash-datom d))
25
+ _hash))
26
+ IEquiv
27
+ (-equiv [d o] (and (instance? Datom o) (equiv-datom d o)))
28
+
29
+ ISeqable
30
+ (-seq [d] (seq-datom d))
31
+
32
+ IFn
33
+ (-invoke [d k] (val-at-datom d k nil))
34
+ (-invoke [d k v] (val-at-datom d k v))
35
+
36
+ ILookup
37
+ (-lookup [d k] (val-at-datom d k nil))
38
+ (-lookup [d k nf] (val-at-datom d k nf))
39
+
40
+ IIndexed
41
+ (-nth [this i] (nth-datom this i))
42
+ (-nth [this i not-found] (nth-datom this i not-found))
43
+
44
+ IAssociative
45
+ (-assoc [d k v] (assoc-datom d k v))
46
+
47
+ IPrintWithWriter
48
+ (-pr-writer [d writer opts]
49
+ (pr-sequential-writer writer pr-writer
50
+ "#datahike/Datom [" " " "]"
51
+ opts [(.-e d) (.-a d) (.-v d) (datom-tx d) (datom-added d)]))]
52
+ :clj
53
+ [Object
54
+ (hashCode [d]
55
+ (if (zero? _hash)
56
+ (let [h (int (hash-datom d))]
57
+ (set! _hash h)
58
+ h)
59
+ _hash))
60
+ (toString [d] (pr-str d))
61
+
62
+ clojure.lang.IHashEq
63
+ (hasheq [d] (.hashCode d))
64
+
65
+ clojure.lang.Seqable
66
+ (seq [d] (seq-datom d))
67
+
68
+ clojure.lang.IPersistentCollection
69
+ (equiv [d o] (and (instance? Datom o) (equiv-datom d o)))
70
+ (empty [d] (throw (UnsupportedOperationException. "empty is not supported on Datom")))
71
+ (count [d] 5)
72
+ (cons [d [k v]] (assoc-datom d k v))
73
+
74
+ clojure.lang.Indexed
75
+ (nth [this i] (nth-datom this i))
76
+ (nth [this i not-found] (nth-datom this i not-found))
77
+
78
+ clojure.lang.IFn
79
+ (invoke [d k] (val-at-datom d k nil))
80
+ (invoke [d k v] (val-at-datom d k v))
81
+
82
+ clojure.lang.ILookup
83
+ (valAt [d k] (val-at-datom d k nil))
84
+ (valAt [d k nf] (val-at-datom d k nf))
85
+
86
+ clojure.lang.Associative
87
+ (entryAt [d k] (some->> (val-at-datom d k nil) (clojure.lang.MapEntry. k)))
88
+ (containsKey [e k] (#{:e :a :v :tx :added} k))
89
+ (assoc [d k v] (assoc-datom d k v))]))
90
+
91
+ #?(:cljs (goog/exportSymbol "datahike.datom.Datom" Datom))
92
+
93
+ (defn ^Datom datom
94
+ ([e a v] (Datom. e a v tx0 0))
95
+ ([e a v tx] (Datom. e a v tx 0))
96
+ ([e a v tx added] (Datom. e a v (if added tx (- tx)) 0)))
97
+
98
+ (defn datom? [x] (instance? Datom x))
99
+
100
+ (defn- hash-datom [^Datom d]
101
+ (-> (hash (.-e d))
102
+ (combine-hashes (hash (.-a d)))
103
+ (combine-hashes (hash (.-v d)))))
104
+
105
+ (defn- equiv-datom [^Datom d ^Datom o]
106
+ (and (== (.-e d) (.-e o))
107
+ (= (.-a d) (.-a o))
108
+ (= (.-v d) (.-v o))))
109
+
110
+ (defn- seq-datom [^Datom d]
111
+ (list (.-e d) (.-a d) (.-v d) (datom-tx d) (datom-added d)))
112
+
113
+ ;; keep it fast by duplicating for both keyword and string cases
114
+ ;; instead of using sets or some other matching func
115
+ (defn- val-at-datom [^Datom d k not-found]
116
+ (case k
117
+ :e (.-e d) "e" (.-e d)
118
+ :a (.-a d) "a" (.-a d)
119
+ :v (.-v d) "v" (.-v d)
120
+ :tx (datom-tx d)
121
+ "tx" (datom-tx d)
122
+ :added (datom-added d)
123
+ "added" (datom-added d)
124
+ not-found))
125
+
126
+ (defn- nth-datom
127
+ ([^Datom d ^long i]
128
+ (case i
129
+ 0 (.-e d)
130
+ 1 (.-a d)
131
+ 2 (.-v d)
132
+ 3 (datom-tx d)
133
+ 4 (datom-added d)
134
+ #?(:clj (throw (IndexOutOfBoundsException.))
135
+ :cljs (throw (js/Error. (str "Datom/-nth: Index out of bounds: " i))))))
136
+ ([^Datom d ^long i not-found]
137
+ (case i
138
+ 0 (.-e d)
139
+ 1 (.-a d)
140
+ 2 (.-v d)
141
+ 3 (datom-tx d)
142
+ 4 (datom-added d)
143
+ not-found)))
144
+
145
+ (defn- ^Datom assoc-datom [^Datom d k v]
146
+ (case k
147
+ :e (datom v (.-a d) (.-v d) (datom-tx d) (datom-added d))
148
+ :a (datom (.-e d) v (.-v d) (datom-tx d) (datom-added d))
149
+ :v (datom (.-e d) (.-a d) v (datom-tx d) (datom-added d))
150
+ :tx (datom (.-e d) (.-a d) (.-v d) v (datom-added d))
151
+ :added (datom (.-e d) (.-a d) (.-v d) (datom-tx d) v)
152
+ (throw (#?(:clj IllegalArgumentException. :cljs js/Error.)
153
+ (str "invalid key for #datahike/Datom: " k)))))
154
+
155
+ ;; printing and reading
156
+ ;; #datomic/DB {:schema <map>, :datoms <vector of [e a v tx]>}
157
+
158
+ (defn ^Datom datom-from-reader [vec]
159
+ (apply datom vec))
160
+
161
+ #?(:clj
162
+ (defmethod print-method Datom [^Datom d, ^java.io.Writer w]
163
+ (.write w (str "#datahike/Datom "))
164
+ (binding [*out* w]
165
+ (pr [(.-e d) (.-a d) (.-v d) (datom-tx d) (datom-added d)]))))
166
+
167
+ ;; ----------------------------------------------------------------------------
168
+ ;; datom cmp macros/funcs
169
+ ;;
170
+
171
+ #?(:clj
172
+ (defmacro combine-cmp [& comps]
173
+ (loop [comps (reverse comps)
174
+ res (num 0)]
175
+ (if (not-empty comps)
176
+ (recur
177
+ (next comps)
178
+ `(let [c# ~(first comps)]
179
+ (if (== 0 c#)
180
+ ~res
181
+ c#)))
182
+ res))))
183
+
184
+ (defn cmp [o1 o2]
185
+ (if (nil? o1) 0
186
+ (if (nil? o2) 0
187
+ (compare o1 o2))))
188
+
189
+ (defn long-cmp [^long a ^long b]
190
+ #?(:clj (Long/compare a b)
191
+ :cljs (- a b)))
192
+
193
+ (defn boolean-cmp [a b]
194
+ #?(:clj (Boolean/compare ^Boolean a ^Boolean b)
195
+ :cljs (- a b)))
196
+
197
+ (comment
198
+ ;; Slower cmp-* fns allows for datom fields to be nil.
199
+ ;; Such datoms come from slice method where they are used as boundary markers.
200
+
201
+ (defn cmp-datoms-eavt [^Datom d1, ^Datom d2]
202
+ (combine-cmp
203
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
204
+ (cmp (.-a d1) (.-a d2))
205
+ (cmp (.-v d1) (.-v d2))
206
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))))
207
+
208
+ (defn cmp-datoms-aevt [^Datom d1, ^Datom d2]
209
+ (combine-cmp
210
+ (cmp (.-a d1) (.-a d2))
211
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
212
+ (cmp (.-v d1) (.-v d2))
213
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))))
214
+
215
+ (defn cmp-datoms-avet [^Datom d1, ^Datom d2]
216
+ (combine-cmp
217
+ (cmp (.-a d1) (.-a d2))
218
+ (cmp (.-v d1) (.-v d2))
219
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
220
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))))
221
+
222
+ (defn cmp-temporal-datoms-eavt [^Datom d1, ^Datom d2]
223
+ (combine-cmp
224
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
225
+ (cmp (.-a d1) (.-a d2))
226
+ (cmp (.-v d1) (.-v d2))
227
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))
228
+ (#?(:clj Boolean/compare :cljs -) (datom-added d1) (datom-added d2))))
229
+
230
+ (defn cmp-temporal-datoms-aevt [^Datom d1, ^Datom d2]
231
+ (combine-cmp
232
+ (cmp (.-a d1) (.-a d2))
233
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
234
+ (cmp (.-v d1) (.-v d2))
235
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))
236
+ (#?(:clj Boolean/compare :cljs -) (datom-added d1) (datom-added d2))))
237
+
238
+ (defn cmp-temporal-datoms-avet [^Datom d1, ^Datom d2]
239
+ (combine-cmp
240
+ (cmp (.-a d1) (.-a d2))
241
+ (cmp (.-v d1) (.-v d2))
242
+ (#?(:clj Long/compare :cljs -) (.-e d1) (.-e d2))
243
+ (#?(:clj Long/compare :cljs -) (datom-tx d1) (datom-tx d2))
244
+ (#?(:clj Boolean/compare :cljs -) (datom-added d1) (datom-added d2)))))
245
+
246
+ ;; fast versions without nil checks
247
+
248
+ (defn cmp-attr-quick [a1 a2]
249
+ ;; either both are keywords or both are strings
250
+ #?(:cljs
251
+ (if (keyword? a1)
252
+ (-compare a1 a2)
253
+ (garray/defaultCompare a1 a2))
254
+ :clj
255
+ (.compareTo ^Comparable a1 a2)))
256
+
257
+ (defn- class-name [x]
258
+ #?(:clj (.getName (class x))
259
+ :cljs (type x)))
260
+
261
+ (defn compare-value
262
+ "Compare two values with cross-platform UUID compatibility.
263
+ CLJS UUID comparison is adjusted to match CLJ's signed comparison,
264
+ ensuring consistent ordering when indices are built on CLJ and queried on CLJS."
265
+ [v1 v2]
266
+ #?(:clj (compare v1 v2)
267
+ :cljs
268
+ (if (and (uuid? v1) (uuid? v2))
269
+ ;; Match Java's signed UUID comparison where MSB is treated as signed
270
+ ;; In signed comparison: 0x8... is negative, so 0x8... < 0x0...
271
+ (let [s1 (.-uuid ^cljs.core/UUID v1)
272
+ s2 (.-uuid ^cljs.core/UUID v2)
273
+ c1 (.charCodeAt s1 0)
274
+ c2 (.charCodeAt s2 0)
275
+ ;; charCode 56 = "8", chars 8-F are "negative" in signed
276
+ neg1 (>= c1 56)
277
+ neg2 (>= c2 56)]
278
+ (cond
279
+ (and neg1 (not neg2)) -1 ;; v1 "negative", v2 "positive" → v1 < v2
280
+ (and neg2 (not neg1)) 1 ;; v2 "negative", v1 "positive" → v1 > v2
281
+ :else (compare s1 s2))) ;; same sign → string compare works
282
+ (compare v1 v2))))
283
+
284
+ (defn- safe-compare [a b]
285
+ (try
286
+ (compare-value a b)
287
+ (catch #?(:clj Exception :cljs js/Error) _e
288
+ (compare (class-name a)
289
+ (class-name b)))))
290
+
291
+ (defn cmp-nil [o1 o2]
292
+ (if (nil? o1) nil
293
+ (if (nil? o2) nil
294
+ (safe-compare o1 o2))))
295
+
296
+ (defn type-hint-datom [x]
297
+ (vary-meta x assoc :tag `Datom))
298
+
299
+ (defn cmp-val [val]
300
+ (case val
301
+ :e (fn [^Datom d1 ^Datom d2] (long-cmp (.-e d1) (.-e d2)))
302
+ :a (fn [^Datom d1 ^Datom d2] (cmp-nil (.-a d1) (.-a d2)))
303
+ :v (fn [^Datom d1 ^Datom d2] (cmp-nil (.-v d1) (.-v d2)))
304
+ :tx (fn [^Datom d1 ^Datom d2] (long-cmp (datom-tx d1) (datom-tx d2)))
305
+ :added (fn [^Datom d1 ^Datom d2] (long-cmp (datom-added d1) (datom-added d2)))))
306
+
307
+ (defn cmp-val-expr [val d1 d2]
308
+ (case val
309
+ :e `(long-cmp (.-e ~d1) (.-e ~d2))
310
+ :a `(cmp-nil (.-a ~d1) (.-a ~d2))
311
+ :v `(cmp-nil (.-v ~d1) (.-v ~d2))
312
+ :tx `(long-cmp (datom-tx ~d1) (datom-tx ~d2))
313
+ :added `(boolean-cmp (datom-added ~d1) (datom-added ~d2))))
314
+
315
+ (defn cmp-datoms-eavt-quick [^Datom d1, ^Datom d2]
316
+ (combine-cmp
317
+ (long-cmp (.-e d1) (.-e d2))
318
+ (cmp-attr-quick (.-a d1) (.-a d2))
319
+ (compare-value (.-v d1) (.-v d2))
320
+ (long-cmp (datom-tx d1) (datom-tx d2))))
321
+
322
+ (defn cmp-datoms-aevt-quick [^Datom d1, ^Datom d2]
323
+ (combine-cmp
324
+ (cmp-attr-quick (.-a d1) (.-a d2))
325
+ (long-cmp (.-e d1) (.-e d2))
326
+ (compare-value (.-v d1) (.-v d2))
327
+ (long-cmp (datom-tx d1) (datom-tx d2))))
328
+
329
+ (defn cmp-datoms-avet-quick [^Datom d1, ^Datom d2]
330
+ (combine-cmp
331
+ (cmp-attr-quick (.-a d1) (.-a d2))
332
+ (compare-value (.-v d1) (.-v d2))
333
+ (long-cmp (.-e d1) (.-e d2))
334
+ (long-cmp (datom-tx d1) (datom-tx d2))))
335
+
336
+ (defn cmp-temporal-datoms-eavt-quick [^Datom d1, ^Datom d2]
337
+ (combine-cmp
338
+ (long-cmp (.-e d1) (.-e d2))
339
+ (cmp-attr-quick (.-a d1) (.-a d2))
340
+ (compare-value (.-v d1) (.-v d2))
341
+ (long-cmp (datom-tx d1) (datom-tx d2))
342
+ (boolean-cmp (datom-added d1) (datom-added d2))))
343
+
344
+ (defn cmp-temporal-datoms-aevt-quick [^Datom d1, ^Datom d2]
345
+ (combine-cmp
346
+ (cmp-attr-quick (.-a d1) (.-a d2))
347
+ (long-cmp (.-e d1) (.-e d2))
348
+ (compare-value (.-v d1) (.-v d2))
349
+ (long-cmp (datom-tx d1) (datom-tx d2))
350
+ (boolean-cmp (datom-added d1) (datom-added d2))))
351
+
352
+ (defn cmp-temporal-datoms-avet-quick [^Datom d1, ^Datom d2]
353
+ (combine-cmp
354
+ (cmp-attr-quick (.-a d1) (.-a d2))
355
+ (compare-value (.-v d1) (.-v d2))
356
+ (long-cmp (.-e d1) (.-e d2))
357
+ (long-cmp (datom-tx d1) (datom-tx d2))
358
+ (boolean-cmp (datom-added d1) (datom-added d2))))
359
+
360
+ ;; Prefix comparators for existence checks (compare e,a,v only, ignoring tx)
361
+ ;; Used by insert to check if ANY datom with same e,a,v exists
362
+ (defn cmp-datoms-eavt-prefix [^Datom d1, ^Datom d2]
363
+ (combine-cmp
364
+ (long-cmp (.-e d1) (.-e d2))
365
+ (cmp-attr-quick (.-a d1) (.-a d2))
366
+ (compare-value (.-v d1) (.-v d2))))
367
+
368
+ (defn cmp-datoms-aevt-prefix [^Datom d1, ^Datom d2]
369
+ (combine-cmp
370
+ (cmp-attr-quick (.-a d1) (.-a d2))
371
+ (long-cmp (.-e d1) (.-e d2))
372
+ (compare-value (.-v d1) (.-v d2))))
373
+
374
+ (defn cmp-datoms-avet-prefix [^Datom d1, ^Datom d2]
375
+ (combine-cmp
376
+ (cmp-attr-quick (.-a d1) (.-a d2))
377
+ (compare-value (.-v d1) (.-v d2))
378
+ (long-cmp (.-e d1) (.-e d2))))
379
+
380
+ (defn diff-sorted [a b cmp]
381
+ (loop [only-a []
382
+ only-b []
383
+ both []
384
+ a a
385
+ b b]
386
+ (cond
387
+ (empty? a) [(not-empty only-a) (not-empty (into only-b b)) (not-empty both)]
388
+ (empty? b) [(not-empty (into only-a a)) (not-empty only-b) (not-empty both)]
389
+ :else
390
+ (let [first-a (first a)
391
+ first-b (first b)
392
+ diff (cmp first-a first-b)]
393
+ (cond
394
+ (== diff 0) (recur only-a only-b (conj both first-a) (next a) (next b))
395
+ (< diff 0) (recur (conj only-a first-a) only-b both (next a) b)
396
+ (> diff 0) (recur only-a (conj only-b first-b) both a (next b)))))))
397
+
398
+ (defn coll->datoms
399
+ "Converts a collection with elements of form [e a v t] into a collection of Datoms."
400
+ [coll]
401
+ (map
402
+ (fn [[e a v t]]
403
+ (datom e a v t))
404
+ coll))
405
+
406
+ (defn index-type->cmp-quick
407
+ ([index-type] (index-type->cmp-quick index-type true))
408
+ ([index-type current?] (if current?
409
+ (case index-type
410
+ :aevt cmp-datoms-aevt-quick
411
+ :avet cmp-datoms-avet-quick
412
+ cmp-datoms-eavt-quick)
413
+ (case index-type
414
+ :aevt cmp-temporal-datoms-aevt-quick
415
+ :avet cmp-temporal-datoms-avet-quick
416
+ cmp-temporal-datoms-eavt-quick))))
417
+
418
+ ;; Comparators for replace operations - only compare key parts, not values
419
+ (defn cmp-datoms-eavt-replace
420
+ "Compare datoms by (e,a) only, ignoring v and tx.
421
+ Used for replace operations where value changes."
422
+ [^Datom d1, ^Datom d2]
423
+ (combine-cmp
424
+ (long-cmp (.-e d1) (.-e d2))
425
+ (cmp-attr-quick (.-a d1) (.-a d2))))
426
+
427
+ (defn cmp-datoms-aevt-replace
428
+ "Compare datoms by (a,e) only, ignoring v and tx.
429
+ Used for replace operations where value changes."
430
+ [^Datom d1, ^Datom d2]
431
+ (combine-cmp
432
+ (cmp-attr-quick (.-a d1) (.-a d2))
433
+ (long-cmp (.-e d1) (.-e d2))))
434
+
435
+ (defn cmp-datoms-avet-replace
436
+ "Compare datoms by (a,e) only, ignoring v and tx.
437
+ Used for replace operations in AVET index where value changes."
438
+ [^Datom d1, ^Datom d2]
439
+ (combine-cmp
440
+ (cmp-attr-quick (.-a d1) (.-a d2))
441
+ (long-cmp (.-e d1) (.-e d2))))
442
+
443
+ (defn index-type->cmp-replace
444
+ "Get comparator for replace operations.
445
+ Only compares the logical key parts, allowing value/tx to differ."
446
+ [index-type]
447
+ (case index-type
448
+ :aevt cmp-datoms-aevt-replace
449
+ :avet cmp-datoms-avet-replace
450
+ cmp-datoms-eavt-replace))
451
+
452
+ (defn index-type->cmp-prefix
453
+ "Get prefix comparator for (e,a,v) matching, ignoring tx.
454
+ Used for existence checks in insert operations."
455
+ [index-type]
456
+ (case index-type
457
+ :aevt cmp-datoms-aevt-prefix
458
+ :avet cmp-datoms-avet-prefix
459
+ cmp-datoms-eavt-prefix))
@@ -0,0 +1,119 @@
1
+ (ns datahike.db.interface)
2
+
3
+ ;; Database Protocols
4
+
5
+ (defrecord SearchContext [historical temporal timepred xform currentdb])
6
+
7
+ (def base-context
8
+ (map->SearchContext
9
+ {:historical false
10
+ :temporal false
11
+ :timepred nil
12
+ :xform nil
13
+ :currentdb nil}))
14
+
15
+ (defn context-historical? [^SearchContext c]
16
+ (.-historical c))
17
+
18
+ (defn context-temporal? [^SearchContext c]
19
+ (.-temporal c))
20
+
21
+ (defn context-time-pred [^SearchContext c]
22
+ (.-timepred c))
23
+
24
+ (defn context-xform [^SearchContext c]
25
+ (.-xform c))
26
+
27
+ (defn context-current-db [^SearchContext c]
28
+ (.-currentdb c))
29
+
30
+ (defn context-set-current-db-if-not-set [^SearchContext c db]
31
+ (if (nil? (.-currentdb c))
32
+ (SearchContext. (.-historical c)
33
+ (.-temporal c)
34
+ (.-timepred c)
35
+ (.-xform c)
36
+ db)
37
+ c))
38
+
39
+ (defn- extend-pred [pred added-pred]
40
+ (if (nil? pred)
41
+ added-pred
42
+ (fn [x] (and (pred x) (added-pred x)))))
43
+
44
+ (defn context-with-temporal-timepred [^SearchContext c timepred]
45
+ (SearchContext. (.-historical c)
46
+ true
47
+ (extend-pred (.-timepred c) timepred)
48
+ (.-xform c)
49
+ (.-currentdb c)))
50
+
51
+ (defn nil-comp [a b]
52
+ (cond
53
+ (nil? a) b
54
+ (nil? b) a
55
+ :else (comp a b)))
56
+
57
+ (defn context-with-xform-after [^SearchContext c xform]
58
+ (SearchContext. (.-historical c)
59
+ (.-temporal c)
60
+ (.-timepred c)
61
+ (nil-comp (.-xform c) xform)
62
+ (.-currentdb c)))
63
+
64
+ (defn context-with-history [^SearchContext c]
65
+ (SearchContext. true
66
+ true
67
+ (.-timepred c)
68
+ (.-xform c)
69
+ (.-currentdb c)))
70
+
71
+ (defprotocol ISearch
72
+ (-search-context [data])
73
+ (-search [data pattern context])
74
+ (-batch-search [data pattern-mask batch-fn context]))
75
+
76
+ (defn search [data pattern]
77
+ (-search data pattern (-search-context data)))
78
+
79
+ (defn batch-search [data pattern-mask batch-fn final-xform]
80
+ (-batch-search data
81
+ pattern-mask
82
+ batch-fn
83
+ (context-with-xform-after (-search-context data)
84
+ final-xform)))
85
+
86
+ (defprotocol IIndexAccess
87
+ (-datoms [db index components context])
88
+ (-seek-datoms [db index components context])
89
+ (-rseek-datoms [db index components context])
90
+ (-index-range [db attr start end context]))
91
+
92
+ (defn datoms [db index components]
93
+ (-datoms db index components (-search-context db)))
94
+
95
+ (defn seek-datoms [db index components]
96
+ (-seek-datoms db index components (-search-context db)))
97
+
98
+ (defn rseek-datoms [db index components]
99
+ (-rseek-datoms db index components (-search-context db)))
100
+
101
+ (defn index-range [db attr start end]
102
+ (-index-range db attr start end (-search-context db)))
103
+
104
+ (defprotocol IDB
105
+ (-schema [db])
106
+ (-rschema [db])
107
+ (-system-entities [db])
108
+ (-attrs-by [db property])
109
+ (-max-tx [db])
110
+ (-max-eid [db])
111
+ (-temporal-index? [db]) ;;deprecated
112
+ (-keep-history? [db])
113
+ (-config [db])
114
+ (-ref-for [db a-ident])
115
+ (-ident-for [db a-ref]))
116
+
117
+ (defprotocol IHistory
118
+ (-time-point [db])
119
+ (-origin [db]))