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,320 @@
1
+ (ns datahike.test.attribute-refs.pull-api-test
2
+ (:require
3
+ #?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
4
+ :clj [clojure.test :as t :refer [is deftest testing]])
5
+ [datahike.test.attribute-refs.utils :refer [ref-db ref-e0 ref-config
6
+ wrap-direct-datoms wrap-ref-datoms]]
7
+ [datahike.api :as d]))
8
+
9
+ (def test-direct-datoms
10
+ [[1 :name "Petr"]
11
+ [1 :aka "Devil"]
12
+ [1 :aka "Tupen"]
13
+ [2 :name "David"]
14
+ [3 :name "Thomas"]
15
+ [4 :name "Lucy"]
16
+ [5 :name "Elizabeth"]
17
+ [6 :name "Matthew"]
18
+ [7 :name "Eunan"]
19
+ [8 :name "Kerri"]
20
+ [9 :name "Rebecca"]
21
+ [10 :name "Part A"]
22
+ [11 :name "Part A.A"]
23
+ [12 :name "Part A.A.A"]
24
+ [13 :name "Part A.A.A.A"]
25
+ [14 :name "Part A.A.A.B"]
26
+ [15 :name "Part A.B"]
27
+ [16 :name "Part A.B.A"]
28
+ [17 :name "Part A.B.A.A"]
29
+ [18 :name "Part A.B.A.B"]])
30
+
31
+ (def test-ref-datoms
32
+ [[1 :child 2]
33
+ [1 :child 3]
34
+ [2 :father 1]
35
+ [3 :father 1]
36
+ [6 :father 3]
37
+ [10 :part 11]
38
+ [11 :part 12]
39
+ [12 :part 13]
40
+ [12 :part 14]
41
+ [10 :part 15]
42
+ [15 :part 16]
43
+ [16 :part 17]
44
+ [16 :part 18]])
45
+
46
+ (defn test-datoms [db offset]
47
+ (vec (concat (wrap-direct-datoms db offset :db/add test-direct-datoms)
48
+ (wrap-ref-datoms db offset :db/add test-ref-datoms))))
49
+
50
+ (def test-db (d/db-with ref-db (test-datoms ref-db ref-e0)))
51
+
52
+ (deftest test-pull-attr-spec
53
+ (is (= {:name "Petr" :aka ["Devil" "Tupen"]}
54
+ (d/pull test-db '[:name :aka] (+ ref-e0 1))))
55
+
56
+ (is (= {:name "Matthew" :father {:db/id (+ ref-e0 3)} :db/id (+ ref-e0 6)}
57
+ (d/pull test-db '[:name :father :db/id] (+ ref-e0 6))))
58
+
59
+ (is (= [{:name "Petr"} {:name "Elizabeth"}
60
+ {:name "Eunan"} {:name "Rebecca"}]
61
+ (d/pull-many test-db '[:name]
62
+ (mapv (partial + ref-e0) [1 5 7 9])))))
63
+
64
+ (deftest test-pull-reverse-attr-spec
65
+ (is (= {:name "David" :_child [{:db/id (+ ref-e0 1)}]}
66
+ (d/pull test-db '[:name :_child] (+ ref-e0 2))))
67
+
68
+ (is (= {:name "David" :_child [{:name "Petr"}]}
69
+ (d/pull test-db '[:name {:_child [:name]}] (+ ref-e0 2))))
70
+
71
+ (testing "Reverse non-component references yield collections"
72
+ (is (= {:name "Thomas" :_father [{:db/id (+ ref-e0 6)}]}
73
+ (d/pull test-db '[:name :_father] (+ ref-e0 3))))
74
+
75
+ (is (= {:name "Petr" :_father [{:db/id (+ ref-e0 2)} {:db/id (+ ref-e0 3)}]}
76
+ (d/pull test-db '[:name :_father] (+ ref-e0 1))))
77
+
78
+ (is (= {:name "Thomas" :_father [{:name "Matthew"}]}
79
+ (d/pull test-db '[:name {:_father [:name]}] (+ ref-e0 3))))
80
+
81
+ (is (= {:name "Petr" :_father [{:name "David"} {:name "Thomas"}]}
82
+ (d/pull test-db '[:name {:_father [:name]}] (+ ref-e0 1))))))
83
+
84
+ (deftest test-pull-component-attr
85
+ (let [parts {:name "Part A",
86
+ :part
87
+ [{:db/id (+ ref-e0 11)
88
+ :name "Part A.A",
89
+ :part
90
+ [{:db/id (+ ref-e0 12)
91
+ :name "Part A.A.A",
92
+ :part
93
+ [{:db/id (+ ref-e0 13) :name "Part A.A.A.A"}
94
+ {:db/id (+ ref-e0 14) :name "Part A.A.A.B"}]}]}
95
+ {:db/id (+ ref-e0 15)
96
+ :name "Part A.B",
97
+ :part
98
+ [{:db/id (+ ref-e0 16)
99
+ :name "Part A.B.A",
100
+ :part
101
+ [{:db/id (+ ref-e0 17) :name "Part A.B.A.A"}
102
+ {:db/id (+ ref-e0 18) :name "Part A.B.A.B"}]}]}]}
103
+ rpart (update-in parts [:part 0 :part 0 :part]
104
+ (partial into [{:db/id (+ ref-e0 10)}]))
105
+ recdb (d/db-with test-db (wrap-ref-datoms test-db ref-e0 :db/add
106
+ [[12 :part 10]]))]
107
+
108
+ (testing "Component entities are expanded recursively"
109
+ (is (= parts (d/pull test-db '[:name :part] (+ ref-e0 10)))))
110
+
111
+ (testing "Reverse component references yield a single result"
112
+ (is (= {:name "Part A.A" :_part {:db/id (+ ref-e0 10)}}
113
+ (d/pull test-db [:name :_part] (+ ref-e0 11))))
114
+
115
+ (is (= {:name "Part A.A" :_part {:name "Part A"}}
116
+ (d/pull test-db [:name {:_part [:name]}] (+ ref-e0 11)))))
117
+
118
+ (testing "Like explicit recursion, expansion will not allow loops"
119
+ (is (= rpart (d/pull recdb '[:name :part] (+ ref-e0 10)))))))
120
+
121
+ (deftest test-pull-wildcard
122
+ (is (= {:db/id (+ ref-e0 1)
123
+ :name "Petr"
124
+ :aka ["Devil" "Tupen"]
125
+ :child [{:db/id (+ ref-e0 2)} {:db/id (+ ref-e0 3)}]}
126
+ (d/pull test-db '[*] (+ ref-e0 1))))
127
+
128
+ (is (= {:db/id (+ ref-e0 2)
129
+ :name "David"
130
+ :_child [{:db/id (+ ref-e0 1)}]
131
+ :father {:db/id (+ ref-e0 1)}}
132
+ (d/pull test-db '[* :_child] (+ ref-e0 2)))))
133
+
134
+ (deftest test-pull-limit
135
+ (let [db (d/db-with test-db
136
+ (concat
137
+ (wrap-ref-datoms test-db ref-e0 :db/add
138
+ [[4 :friend 5]
139
+ [4 :friend 6]
140
+ [4 :friend 7]
141
+ [4 :friend 8]])
142
+ (wrap-direct-datoms test-db ref-e0 :db/add
143
+ (for [idx (range 2000)]
144
+ [8 :aka (str "aka-" idx)]))))]
145
+
146
+ (testing "Without an explicit limit, the default is 1000"
147
+ (is (= 1000 (->> (d/pull db '[:aka] (+ ref-e0 8)) :aka count))))
148
+
149
+ (testing "Explicit limit can reduce the default"
150
+ (is (= 500 (->> (d/pull db '[(limit :aka 500)] (+ ref-e0 8)) :aka count)))
151
+ (is (= 500 (->> (d/pull db '[[:aka :limit 500]] (+ ref-e0 8)) :aka count))))
152
+
153
+ (testing "Explicit limit can increase the default"
154
+ (is (= 1500 (->> (d/pull db '[(limit :aka 1500)] (+ ref-e0 8)) :aka count))))
155
+
156
+ (testing "A nil limit produces unlimited results"
157
+ (is (= 2000 (->> (d/pull db '[(limit :aka nil)] (+ ref-e0 8)) :aka count))))
158
+
159
+ (testing "Limits can be used as map specification keys"
160
+ (is (= {:name "Lucy"
161
+ :friend [{:name "Elizabeth"} {:name "Matthew"}]}
162
+ (d/pull db '[:name {(limit :friend 2) [:name]}] (+ ref-e0 4)))))))
163
+
164
+ (deftest test-pull-default
165
+ (testing "Empty results return nil"
166
+ (is (nil? (d/pull test-db '[:foo] (+ ref-e0 1)))))
167
+
168
+ (testing "A default can be used to replace nil results"
169
+ (is (= {:foo "bar"}
170
+ (d/pull test-db '[(default :foo "bar")] (+ ref-e0 1))))
171
+ (is (= {:foo "bar"}
172
+ (d/pull test-db '[[:foo :default "bar"]] (+ ref-e0 1))))))
173
+
174
+ (deftest test-pull-as
175
+ (is (= {"Name" "Petr", :alias ["Devil" "Tupen"]}
176
+ (d/pull test-db '[[:name :as "Name"] [:aka :as :alias]] (+ ref-e0 1)))))
177
+
178
+ (deftest test-pull-attr-with-opts
179
+ (is (= {"Name" "Nothing"}
180
+ (d/pull test-db '[[:x :as "Name" :default "Nothing"]] (+ ref-e0 1)))))
181
+
182
+ (deftest test-pull-map
183
+ (testing "Single attrs yield a map"
184
+ (is (= {:name "Matthew" :father {:name "Thomas"}}
185
+ (d/pull test-db '[:name {:father [:name]}] (+ ref-e0 6)))))
186
+
187
+ (testing "Multi attrs yield a collection of maps"
188
+ (is (= {:name "Petr" :child [{:name "David"}
189
+ {:name "Thomas"}]}
190
+ (d/pull test-db '[:name {:child [:name]}] (+ ref-e0 1)))))
191
+
192
+ (testing "Missing attrs are dropped"
193
+ (is (= {:name "Petr"}
194
+ (d/pull test-db '[:name {:father [:name]}] (+ ref-e0 1)))))
195
+
196
+ (testing "Non matching results are removed from collections"
197
+ (is (= {:name "Petr" :child []}
198
+ (d/pull test-db '[:name {:child [:foo]}] (+ ref-e0 1)))))
199
+
200
+ (testing "Map specs can override component expansion"
201
+ (let [parts {:name "Part A" :part [{:name "Part A.A"} {:name "Part A.B"}]}]
202
+ (is (= parts
203
+ (d/pull test-db '[:name {:part [:name]}] (+ ref-e0 10))))
204
+
205
+ (is (= parts
206
+ (d/pull test-db '[:name {:part 1}] (+ ref-e0 10)))))))
207
+
208
+ (deftest test-pull-recursion
209
+ (let [irmap (get test-db :ident-ref-map)
210
+ datoms [[4 :friend 5]
211
+ [5 :friend 6]
212
+ [6 :friend 7]
213
+ [7 :friend 8]
214
+ [4 :enemy 6]
215
+ [5 :enemy 7]
216
+ [6 :enemy 8]
217
+ [7 :enemy 4]]
218
+ db (d/db-with test-db (wrap-ref-datoms test-db ref-e0 :db/add datoms))
219
+ friends {:db/id (+ ref-e0 4)
220
+ :name "Lucy"
221
+ :friend
222
+ [{:db/id (+ ref-e0 5)
223
+ :name "Elizabeth"
224
+ :friend
225
+ [{:db/id (+ ref-e0 6)
226
+ :name "Matthew"
227
+ :friend
228
+ [{:db/id (+ ref-e0 7)
229
+ :name "Eunan"
230
+ :friend
231
+ [{:db/id (+ ref-e0 8)
232
+ :name "Kerri"}]}]}]}]}
233
+ enemies {:db/id (+ ref-e0 4) :name "Lucy"
234
+ :friend
235
+ [{:db/id (+ ref-e0 5) :name "Elizabeth"
236
+ :friend
237
+ [{:db/id (+ ref-e0 6) :name "Matthew"
238
+ :enemy [{:db/id (+ ref-e0 8) :name "Kerri"}]}]
239
+ :enemy
240
+ [{:db/id (+ ref-e0 7) :name "Eunan"
241
+ :friend
242
+ [{:db/id (+ ref-e0 8) :name "Kerri"}]
243
+ :enemy
244
+ [{:db/id (+ ref-e0 4) :name "Lucy"
245
+ :friend [{:db/id (+ ref-e0 5)}]}]}]}]
246
+ :enemy
247
+ [{:db/id (+ ref-e0 6) :name "Matthew"
248
+ :friend
249
+ [{:db/id (+ ref-e0 7) :name "Eunan"
250
+ :friend
251
+ [{:db/id (+ ref-e0 8) :name "Kerri"}]
252
+ :enemy [{:db/id (+ ref-e0 4) :name "Lucy"
253
+ :friend [{:db/id (+ ref-e0 5) :name "Elizabeth"}]}]}]
254
+ :enemy
255
+ [{:db/id (+ ref-e0 8) :name "Kerri"}]}]}]
256
+
257
+ (testing "Infinite recursion"
258
+ (is (= friends (d/pull db '[:db/id :name {:friend ...}] (+ ref-e0 4)))))
259
+
260
+ (testing "Multiple recursion specs in one pattern"
261
+ (is (= enemies (d/pull db '[:db/id :name {:friend 2 :enemy 2}] (+ ref-e0 4)))))
262
+
263
+ (let [db (d/db-with db [[:db/add (+ ref-e0 8) (:friend irmap) (+ ref-e0 4)]])]
264
+ (testing "Cycles are handled by returning only the :db/id of entities which have been seen before"
265
+ (is (= (update-in friends (take 8 (cycle [:friend 0]))
266
+ assoc :friend [{:db/id (+ ref-e0 4) :name "Lucy" :friend [{:db/id (+ ref-e0 5)}]}])
267
+ (d/pull db '[:db/id :name {:friend ...}] (+ ref-e0 4))))))))
268
+
269
+ (deftest test-dual-recursion
270
+ (let [_ (d/delete-database ref-config)
271
+ _ (d/create-database ref-config)
272
+ conn (d/connect ref-config)
273
+ schema [{:db/ident :part
274
+ :db/cardinality :db.cardinality/one
275
+ :db/valueType :db.type/ref}
276
+ {:db/ident :spec
277
+ :db/cardinality :db.cardinality/one
278
+ :db/valueType :db.type/ref}]
279
+ _ (d/transact conn schema)
280
+ test-e0 (:max-eid @conn)
281
+ db (d/db-with @conn (wrap-ref-datoms @conn test-e0 :db/add
282
+ [[1 :part 2]
283
+ [2 :part 3]
284
+ [3 :part 1]
285
+ [1 :spec 2]
286
+ [2 :spec 1]]))]
287
+ (is (= (d/pull db '[:db/id {:part ...} {:spec ...}] (+ test-e0 1))
288
+ {:db/id (+ test-e0 1),
289
+ :spec {:db/id (+ test-e0 2)
290
+ :spec {:db/id (+ test-e0 1),
291
+ :spec {:db/id (+ test-e0 2)}, :part {:db/id (+ test-e0 2)}}
292
+ :part {:db/id (+ test-e0 3),
293
+ :part {:db/id (+ test-e0 1),
294
+ :spec {:db/id (+ test-e0 2)},
295
+ :part {:db/id (+ test-e0 2)}}}}
296
+ :part {:db/id (+ test-e0 2)
297
+ :spec {:db/id (+ test-e0 1), :spec {:db/id (+ test-e0 2)}, :part {:db/id (+ test-e0 2)}}
298
+ :part {:db/id (+ test-e0 3),
299
+ :part {:db/id (+ test-e0 1),
300
+ :spec {:db/id (+ test-e0 2)},
301
+ :part {:db/id (+ test-e0 2)}}}}}))
302
+ (d/release conn)))
303
+
304
+ (deftest test-deep-recursion
305
+ (let [start 100
306
+ depth 1500
307
+ irmap (get test-db :ident-ref-map)
308
+ txd (mapcat
309
+ (fn [idx]
310
+ [[:db/add idx (:name irmap) (str "Person-" idx)]
311
+ [:db/add (dec idx) (:friend irmap) idx]])
312
+ (range (inc start) depth))
313
+ db (d/db-with test-db
314
+ (concat txd [[:db/add start (:name irmap) (str "Person-" start)]]))
315
+ pulled (d/pull db '[:name {:friend ...}] start)
316
+ path (->> [:friend 0]
317
+ (repeat (dec (- depth start)))
318
+ (into [] cat))]
319
+ (is (= (str "Person-" (dec depth))
320
+ (:name (get-in pulled path))))))
@@ -0,0 +1,59 @@
1
+ (ns datahike.test.attribute-refs.query-find-specs-test
2
+ (:require
3
+ #?(:cljs [cljs.test :as t :refer-macros [deftest testing is]]
4
+ :clj [clojure.test :as t :refer [deftest testing is]])
5
+ [datahike.test.attribute-refs.utils :refer [ref-db ref-e0
6
+ wrap-direct-datoms]]
7
+ [datahike.api :as d]))
8
+
9
+ (def test-db (d/db-with
10
+ ref-db
11
+ (wrap-direct-datoms ref-db ref-e0 :db/add
12
+ [[1 :name "Petr"]
13
+ [1 :age 44]
14
+ [2 :name "Ivan"]
15
+ [2 :age 25]
16
+ [3 :name "Sergey"]
17
+ [3 :age 11]])))
18
+
19
+ (deftest test-find-specs
20
+ (is (= #{"Ivan" "Petr" "Sergey"}
21
+ (set (d/q '[:find [?name ...]
22
+ :where [_ :name ?name]]
23
+ test-db))))
24
+ (is (= ["Petr" 44]
25
+ (d/q [:find ['?name '?age] :where
26
+ [(+ ref-e0 1) :name '?name]
27
+ [(+ ref-e0 1) :age '?age]]
28
+ test-db)))
29
+ (is (= "Petr"
30
+ (d/q [:find '?name '. :where
31
+ [(+ ref-e0 1) :name '?name]]
32
+ test-db)))
33
+
34
+ (testing "Multiple results get cut"
35
+ (is (contains?
36
+ #{["Petr" 44] ["Ivan" 25] ["Sergey" 11]}
37
+ (d/q '[:find [?name ?age]
38
+ :where [?e :name ?name]
39
+ [?e :age ?age]]
40
+ test-db)))
41
+ (is (contains?
42
+ #{"Ivan" "Petr" "Sergey"}
43
+ (d/q '[:find ?name .
44
+ :where [_ :name ?name]]
45
+ test-db))))
46
+
47
+ (testing "Aggregates work with find specs"
48
+ (is (= [3]
49
+ (d/q '[:find [(count ?name) ...]
50
+ :where [_ :name ?name]]
51
+ test-db)))
52
+ (is (= [3]
53
+ (d/q '[:find [(count ?name)]
54
+ :where [_ :name ?name]]
55
+ test-db)))
56
+ (is (= 3
57
+ (d/q '[:find (count ?name) .
58
+ :where [_ :name ?name]]
59
+ test-db)))))
@@ -0,0 +1,130 @@
1
+ (ns datahike.test.attribute_refs.query-fns-test
2
+ (:require
3
+ #?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]]
4
+ :clj [clojure.test :as t :refer [is are deftest testing]])
5
+ [datahike.core :as d]
6
+ [datahike.test.attribute-refs.utils :refer [ref-db ref-e0 shift-entities]])
7
+ #?(:clj
8
+ (:import [clojure.lang ExceptionInfo])))
9
+
10
+ (deftest test-query-fns
11
+ (let [entities [{:db/id 1, :name "Ivan", :age 15}
12
+ {:db/id 2, :name "Petr", :age 22, :height 240, :parent (+ ref-e0 1)}
13
+ {:db/id 3, :name "Slava", :age 37, :parent (+ ref-e0 2)}]
14
+ db (d/db-with ref-db (shift-entities ref-e0 entities))]
15
+
16
+ (testing "get-else"
17
+ (is (= (d/q '[:find ?age ?height
18
+ :where [?e :age ?age]
19
+ [(get-else $ ?e :height 300) ?height]] db)
20
+ #{[15 300] [22 240] [37 300]}))
21
+
22
+ (is (thrown-with-msg? ExceptionInfo #"get-else: nil default value is not supported"
23
+ (d/q '[:find ?e ?height
24
+ :where [?e :age]
25
+ [(get-else $ ?e :height nil) ?height]] db))))
26
+
27
+ (testing "get-some"
28
+ (is (= #{[:age 15]
29
+ [:height 240]
30
+ [:age 37]}
31
+ (d/q '[:find ?a ?v
32
+ :where [?e :name _]
33
+ [(get-some $ ?e :height :age) [?a ?v]]] db))))
34
+
35
+ (testing "missing?"
36
+ (is (= #{[15] [37]}
37
+ (d/q '[:find ?age
38
+ :in $
39
+ :where [?e :age ?age]
40
+ [(missing? $ ?e :height)]] db))))
41
+
42
+ (testing "missing? back-ref"
43
+ (is (= #{[(+ ref-e0 3)]}
44
+ (d/q '[:find ?e
45
+ :in $
46
+ :where [?e :age ?age]
47
+ [(missing? $ ?e :_parent)]] db))))
48
+
49
+ (testing "Built-ins"
50
+ (is (= #{[(+ ref-e0 1) (+ ref-e0 2)] [(+ ref-e0 1) (+ ref-e0 3)]}
51
+ (d/q '[:find ?e1 ?e2
52
+ :where [?e1 :age ?a1]
53
+ [?e2 :age ?a2]
54
+ [(< ?a1 18 ?a2)]] db))))
55
+
56
+ (testing "Passing predicate as source"
57
+ (is (= #{[(+ ref-e0 2)] [(+ ref-e0 3)]}
58
+ (d/q '[:find ?e
59
+ :in $ ?adult
60
+ :where [?e :age ?a]
61
+ [(?adult ?a)]]
62
+ db
63
+ #(> % 18)))))
64
+
65
+ (testing "Calling a function"
66
+ (is (= #{[(+ ref-e0 1) (+ ref-e0 2) (+ ref-e0 3)] [(+ ref-e0 2) (+ ref-e0 1) (+ ref-e0 3)]}
67
+ (d/q '[:find ?e1 ?e2 ?e3
68
+ :where [?e1 :age ?a1]
69
+ [?e2 :age ?a2]
70
+ [?e3 :age ?a3]
71
+ [(+ ?a1 ?a2) ?a12]
72
+ [(= ?a12 ?a3)]]
73
+ db))))
74
+
75
+ (testing "Two conflicting function values for one binding."
76
+ (is (= #{}
77
+ (d/q '[:find ?n
78
+ :where [(identity 1) ?n]
79
+ [(identity 2) ?n]]
80
+ db))))
81
+
82
+ (testing "Destructured conflicting function values for two bindings."
83
+ (is (= #{}
84
+ (d/q '[:find ?n ?x
85
+ :where [(identity [3 4]) [?n ?x]]
86
+ [(identity [1 2]) [?n ?x]]]
87
+ db))))
88
+
89
+ (testing "Rule bindings interacting with function binding. (fn, rule)"
90
+ (is (= #{[2]}
91
+ (d/q '[:find ?n
92
+ :in $ %
93
+ :where [(identity 2) ?n]
94
+ (my-vals ?n)]
95
+ db
96
+ '[[(my-vals ?x)
97
+ [(identity 1) ?x]]
98
+ [(my-vals ?x)
99
+ [(identity 2) ?x]]
100
+ [(my-vals ?x)
101
+ [(identity 3) ?x]]]))))
102
+
103
+ (testing "Rule bindings interacting with function binding. (rule, fn)"
104
+ (is (= #{[2]}
105
+ (d/q '[:find ?n
106
+ :in $ %
107
+ :where (my-vals ?n)
108
+ [(identity 2) ?n]]
109
+ db
110
+ '[[(my-vals ?x)
111
+ [(identity 1) ?x]]
112
+ [(my-vals ?x)
113
+ [(identity 2) ?x]]
114
+ [(my-vals ?x)
115
+ [(identity 3) ?x]]]))))
116
+
117
+ (testing "Conflicting relational bindings with function binding. (rel, fn)"
118
+ (is (= #{}
119
+ (d/q '[:find ?age
120
+ :where [_ :age ?age]
121
+ [(identity 100) ?age]]
122
+ db))))
123
+
124
+ (testing "Conflicting relational bindings with function binding. (fn, rel)"
125
+ (is (= #{}
126
+ (d/q '[:find ?age
127
+ :where [(identity 100) ?age]
128
+ [_ :age ?age]]
129
+ db))))))
130
+
@@ -0,0 +1,47 @@
1
+ (ns datahike.test.attribute-refs.query-interop-test
2
+ (:require
3
+ #?(:cljs [cljs.test :as t :refer-macros [deftest is are]]
4
+ :clj [clojure.test :as t :refer [deftest is are]])
5
+ [datahike.test.attribute-refs.utils :refer [ref-db ref-e0
6
+ wrap-direct-datoms]]
7
+ [datahike.api :as d]))
8
+
9
+ #?(:cljs (def Exception js/Error))
10
+
11
+ (def test-db
12
+ (d/db-with ref-db
13
+ (wrap-direct-datoms ref-db ref-e0 :db/add [[1 :name "Vlad"]
14
+ [2 :name "Ivan"]
15
+ [3 :name "Sergey"]])))
16
+
17
+ (deftest test-filter
18
+ (are [q expected] (= (d/q q test-db) expected)
19
+ '[:find ?v
20
+ :where [_ :name ?v]
21
+ [(.startsWith ?v "Ser")]]
22
+ #{["Sergey"]}
23
+
24
+ '[:find ?v
25
+ :where [_ :name ?v]
26
+ [(.contains ?v "a")]]
27
+ #{["Vlad"] ["Ivan"]}
28
+
29
+ '[:find ?v
30
+ :where [_ :name ?v]
31
+ [(.matches ?v ".+rg.+")]]
32
+ #{["Sergey"]}))
33
+
34
+ (deftest test-bind
35
+ (are [q expected] (= (d/q q test-db) expected)
36
+ '[:find ?V
37
+ :where
38
+ [?e :name ?v]
39
+ [(.toLowerCase ?v) ?V]]
40
+ #{["vlad"] ["ivan"] ["sergey"]}))
41
+
42
+ (deftest test-method-not-found
43
+ (is (thrown? Exception (d/q '[:find ?v
44
+ :where
45
+ [?e :name ?v]
46
+ [(.thisMethodDoesNotExist ?v 1)]]
47
+ test-db))))