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,305 @@
1
+ (ns datahike.db.search
2
+ (:require
3
+ #?(:clj [clojure.core.cache.wrapped :as cw]
4
+ :cljs [cljs.cache.wrapped :as cw])
5
+ [datahike.array :refer [a=]]
6
+ [datahike.constants :refer [e0 tx0 emax txmax]]
7
+ [datahike.datom :refer [datom datom-tx datom-added type-hint-datom]]
8
+ [datahike.db.utils :as dbu]
9
+ [datahike.index :as di]
10
+ [datahike.lru :refer [lru-datom-cache-factory]]
11
+ [datahike.tools :refer [raise match-vector]]
12
+ [environ.core :refer [env]])
13
+ #?(:cljs (:require-macros [datahike.db.search :refer [lookup-strategy]]))
14
+ #?(:clj (:import [datahike.datom Datom])))
15
+
16
+ (def db-caches (cw/lru-cache-factory {} :threshold (:datahike-max-db-caches env 5)))
17
+
18
+ (defn memoize-for [db key f]
19
+ (if (or (zero? (or (:cache-size (:config db)) 0))
20
+ (zero? (:hash db))) ;; empty db
21
+ (f)
22
+ (let [db-cache (cw/lookup-or-miss db-caches
23
+ (:hash db)
24
+ (fn [_] (lru-datom-cache-factory {} :threshold (:cache-size (:config db)))))]
25
+ (cw/lookup-or-miss db-cache key (fn [_] (f))))))
26
+
27
+ (defn validate-pattern
28
+ "Checks if database pattern is valid"
29
+ [db pattern can-have-vars]
30
+ (let [bound-var? (if can-have-vars symbol? (fn [_] false))
31
+ [e a v tx added?] pattern]
32
+
33
+ (when-not (or (number? e)
34
+ (nil? e)
35
+ (bound-var? e)
36
+ (and (vector? e) (= 2 (count e))))
37
+ (raise "Bad format for entity-id in pattern, must be a number, nil or vector of two elements."
38
+ {:error :search/pattern :e e :pattern pattern}))
39
+
40
+ (when-not (or (number? a)
41
+ (keyword? a)
42
+ (bound-var? a)
43
+ (nil? a))
44
+ (raise "Bad format for attribute in pattern, must be a number, nil or a keyword."
45
+ {:error :search/pattern :a a :pattern pattern}))
46
+
47
+ ;; Value validation: allow vectors of any length for tuple attributes
48
+ (when-not (or (not (vector? v))
49
+ (nil? v)
50
+ (bound-var? v)
51
+ ;; Allow 2-element vectors for lookup refs (when attr is ref type)
52
+ (and (vector? v) (= 2 (count v)))
53
+ ;; Allow any-length vectors for tuple values
54
+ (and (vector? v) a (dbu/tuple? db a)))
55
+ (raise "Bad format for value in pattern, must be a scalar, nil or a vector of two elements."
56
+ {:error :search/pattern :v v :pattern pattern}))
57
+
58
+ (when-not (or (nil? tx)
59
+ (bound-var? tx)
60
+ (number? tx))
61
+ (raise "Bad format for transaction ID in pattern, must be a number or nil."
62
+ {:error :search/pattern :tx tx :pattern pattern}))
63
+
64
+ (when-not (or (nil? added?)
65
+ (boolean? added?)
66
+ (bound-var? added?))
67
+ (raise "Bad format for added? in pattern, must be a boolean value or nil."
68
+ {:error :search/pattern :added? added? :pattern pattern}))))
69
+
70
+ (defn short-hand->strat-symbol [x]
71
+ (case x
72
+ 1 :substitute
73
+ f :filter
74
+ _ nil
75
+ :substitute :substitute
76
+ :filter :filter
77
+ nil nil))
78
+
79
+ (defn datom-expr [[esym asym vsym tsym]
80
+ [e-strat a-strat v-strat t-strat]
81
+ e-bound
82
+ tx-bound]
83
+ (let [subst (fn [expr strategy bound]
84
+ (case strategy
85
+ :substitute expr
86
+ bound))]
87
+ `(datom ~(subst esym e-strat e-bound)
88
+ ~(subst asym a-strat nil)
89
+ ~(subst vsym v-strat nil)
90
+ ~(subst tsym t-strat tx-bound))))
91
+
92
+ (defn lookup-strategy-sub [index-key eavt-symbols eavt-strats]
93
+ (let [[_ _ v-strat t-strat] eavt-strats
94
+ [_ _ v-sym t-sym] eavt-symbols
95
+ strat-set (set eavt-strats)
96
+ has-substitution (contains? strat-set :substitute)
97
+ index-expr (symbol index-key)
98
+
99
+ lower-datom (datom-expr eavt-symbols eavt-strats 'e0 'tx0)
100
+ upper-datom (datom-expr eavt-symbols eavt-strats 'emax 'txmax)
101
+
102
+ ;; Either get all datoms or a subset where some values in the
103
+ ;; datom are fixed.
104
+ lookup-expr (if has-substitution
105
+ `(di/-slice ~index-expr
106
+ ~lower-datom
107
+ ~upper-datom
108
+ ~index-key)
109
+ `(di/-all ~index-expr))
110
+
111
+ ;; Symbol type-hinted as Datom.
112
+ dexpr (type-hint-datom (gensym))
113
+
114
+ ;; Equalities used for filtering (in conjunction)
115
+ equalities (remove nil? [(when (= :filter v-strat)
116
+ `(a= ~v-sym (.-v ~dexpr)))
117
+ (when (= :filter t-strat)
118
+ `(= ~t-sym (datom-tx ~dexpr)))])
119
+ added (gensym)]
120
+ `{:index-key ~index-key
121
+ :strategy-vec ~(vec eavt-strats)
122
+ :lookup-fn (fn [~index-expr ~eavt-symbols]
123
+ ~(if (seq equalities)
124
+ `(filter (fn [~dexpr] (and ~@equalities)) ~lookup-expr)
125
+ lookup-expr))
126
+ :backend-fn (fn [~index-expr]
127
+ (fn [~@eavt-symbols ~added]
128
+ ~lookup-expr))}))
129
+
130
+ (defmacro lookup-strategy [index-key & eavt-strats]
131
+ {:pre [(keyword? index-key)]}
132
+ (let [pattern-symbols '[e a v tx]]
133
+ (lookup-strategy-sub index-key
134
+ pattern-symbols
135
+ (map short-hand->strat-symbol eavt-strats))))
136
+
137
+ (defn- get-search-strategy-impl [e a v t i]
138
+ (match-vector [e a v t i]
139
+ [e a v t *] (lookup-strategy :eavt 1 1 1 1)
140
+ [e a v _ *] (lookup-strategy :eavt 1 1 1 _)
141
+ [e a _ t *] (lookup-strategy :eavt 1 1 _ f)
142
+ [e a _ _ *] (lookup-strategy :eavt 1 1 _ _)
143
+ [e _ v t *] (lookup-strategy :eavt 1 _ f f)
144
+ [e _ v _ *] (lookup-strategy :eavt 1 _ f _)
145
+ [e _ _ t *] (lookup-strategy :eavt 1 _ _ f)
146
+ [e _ _ _ *] (lookup-strategy :eavt 1 _ _ _)
147
+ [_ a v t i] (lookup-strategy :avet _ 1 1 f)
148
+ [_ a v t _] (lookup-strategy :aevt _ 1 f f)
149
+ [_ a v _ i] (lookup-strategy :avet _ 1 1 _)
150
+ [_ a v _ _] (lookup-strategy :aevt _ 1 f _)
151
+ [_ a _ t *] (lookup-strategy :aevt _ 1 _ f)
152
+ [_ a _ _ *] (lookup-strategy :aevt _ 1 _ _)
153
+ [_ _ v t *] (lookup-strategy :eavt _ _ f f)
154
+ [_ _ v _ *] (lookup-strategy :eavt _ _ f _)
155
+ [_ _ _ t *] (lookup-strategy :eavt _ _ _ f)
156
+ [_ _ _ _ *] (lookup-strategy :eavt _ _ _ _)))
157
+
158
+ (defn empty-lookup-fn
159
+ ([_db-index [_e _a _v _tx]]
160
+ [])
161
+ ([_db-index [_e _a _v _tx] _batch-fn]
162
+ []))
163
+
164
+ (defn- get-search-strategy [db pattern indexed? temporal-db?]
165
+ (validate-pattern db pattern true)
166
+ (let [[e a v tx added?] pattern]
167
+ (when-not (and (not temporal-db?) (false? added?))
168
+ (get-search-strategy-impl
169
+ (boolean e)
170
+ (boolean a)
171
+ (some? v)
172
+ (boolean tx)
173
+ (boolean indexed?)))))
174
+
175
+ (defn- resolve-db-index [strategy index-map]
176
+ (when strategy
177
+ (assoc strategy
178
+ :db-index
179
+ (get index-map (:index-key strategy)))))
180
+
181
+ (defn- indexing-for-pattern? [db pattern]
182
+ (let [[_ a _ _] pattern]
183
+ (dbu/indexing? db a)))
184
+
185
+ (defn search-strategy-with-index [db pattern temporal?]
186
+ (-> (get-search-strategy db
187
+ pattern
188
+ (indexing-for-pattern? db pattern)
189
+ temporal?)
190
+ (resolve-db-index (if temporal?
191
+ {:eavt (:temporal-eavt db)
192
+ :aevt (:temporal-aevt db)
193
+ :avet (:temporal-avet db)}
194
+ db))))
195
+
196
+ (defn search-current-indices
197
+ ([db pattern]
198
+ (memoize-for
199
+ db [:search pattern]
200
+ #(if-let [{:keys [db-index lookup-fn]}
201
+ (search-strategy-with-index db pattern false)]
202
+ (lookup-fn db-index pattern)
203
+ [])))
204
+
205
+ ;; For batches
206
+ ([db pattern batch-fn]
207
+ (if-let [{:keys [db-index strategy-vec backend-fn]}
208
+ (search-strategy-with-index db pattern false)]
209
+ (batch-fn strategy-vec (backend-fn db-index) identity)
210
+ [])))
211
+
212
+ (defn added? [[_ _ _ _ added]]
213
+ added)
214
+
215
+ (defn filter-by-added
216
+ ([pattern]
217
+ (case (added? pattern)
218
+ true (filter datom-added)
219
+ false (remove datom-added)
220
+ identity))
221
+ ([pattern result]
222
+ (case (added? pattern)
223
+ true (filter datom-added result)
224
+ false (remove datom-added result)
225
+ result)))
226
+
227
+ (defn search-temporal-indices
228
+ ([db pattern]
229
+ (validate-pattern db pattern false)
230
+ (memoize-for db [:temporal-search pattern]
231
+ #(if-let [{:keys [db-index lookup-fn]}
232
+ (search-strategy-with-index
233
+ db pattern true)]
234
+ (let [result (lookup-fn db-index pattern)]
235
+ (filter-by-added pattern result))
236
+ [])))
237
+ ([db pattern batch-fn]
238
+ (validate-pattern db pattern true)
239
+ (if-let [{:keys [db-index strategy-vec backend-fn]}
240
+ (search-strategy-with-index
241
+ db pattern true)]
242
+ (batch-fn strategy-vec (backend-fn db-index)
243
+ (filter-by-added pattern))
244
+ [])))
245
+
246
+ (defn index-type [db pattern]
247
+ (let [idx (indexing-for-pattern? db pattern)
248
+ a (:index-key (get-search-strategy db pattern idx false))
249
+ b (:index-key (get-search-strategy db pattern idx true))]
250
+ (assert (or (nil? a) (keyword? a)))
251
+ (assert (or (nil? b) (keyword? b)))
252
+ (when (= a b)
253
+ a)))
254
+
255
+ (defn temporal-search
256
+ ([db pattern]
257
+ (validate-pattern db pattern false)
258
+ (dbu/distinct-datoms
259
+ db
260
+ (index-type db pattern)
261
+ (search-current-indices db pattern)
262
+ (search-temporal-indices db pattern)))
263
+ ([db pattern batch-fn]
264
+ (validate-pattern db pattern true)
265
+ (dbu/distinct-datoms
266
+ db
267
+ (index-type db pattern)
268
+ (search-current-indices db pattern batch-fn)
269
+ (search-temporal-indices db pattern batch-fn))))
270
+
271
+ (defn temporal-seek-datoms [db index-type cs]
272
+ (let [index (get db index-type)
273
+ temporal-index (get db (keyword (str "temporal-" (name index-type))))
274
+ from (dbu/components->pattern db index-type cs e0 tx0)
275
+ to (datom emax nil nil txmax)]
276
+ (dbu/distinct-datoms db
277
+ index-type
278
+ (di/-slice index from to index-type)
279
+ (di/-slice temporal-index from to index-type))))
280
+
281
+ (defn temporal-rseek-datoms [db index-type cs]
282
+ (let [index (get db index-type)
283
+ temporal-index (get db (keyword (str "temporal-" (name index-type))))
284
+ from (dbu/components->pattern db index-type cs e0 tx0)
285
+ to (datom emax nil nil txmax)]
286
+ (concat
287
+ (-> (dbu/distinct-datoms db
288
+ index-type
289
+ (di/-slice index from to index-type)
290
+ (di/-slice temporal-index from to index-type))
291
+ vec
292
+ rseq))))
293
+
294
+ (defn temporal-index-range [db current-db attr start end]
295
+ (when-not (dbu/indexing? db attr)
296
+ (raise "Attribute" attr "should be marked as :db/index true" {}))
297
+ (dbu/validate-attr attr (list '-index-range 'db attr start end) db)
298
+ (let [from (dbu/resolve-datom current-db nil attr start nil e0 tx0)
299
+ to (dbu/resolve-datom current-db nil attr end nil emax txmax)]
300
+ (dbu/distinct-datoms db
301
+ :avet
302
+ (di/-slice (:avet db) from to :avet)
303
+ (di/-slice (:temporal-avet db) from to :avet))))
304
+
305
+