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,266 @@
1
+ (ns datahike.test.lookup-refs-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.api :as d]
6
+ [datahike.db :as db]
7
+ [datahike.test.core-test :as tdc]))
8
+
9
+ #?(:cljs (def Throwable js/Error))
10
+
11
+ (deftest test-lookup-refs
12
+ (let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/identity}
13
+ :email {:db/unique :db.unique/value}})
14
+ [{:db/id 1 :name "Ivan" :email "@1" :age 35}
15
+ {:db/id 2 :name "Petr" :email "@2" :age 22}])]
16
+
17
+ (are [eid res] (= (tdc/entity-map db eid) res)
18
+ [:name "Ivan"] {:db/id 1 :name "Ivan" :email "@1" :age 35}
19
+ [:email "@1"] {:db/id 1 :name "Ivan" :email "@1" :age 35}
20
+ [:name "Sergey"] nil
21
+ [:name nil] nil)
22
+
23
+ (are [eid msg] (thrown-with-msg? Throwable msg (d/entity db eid))
24
+ [:name] #"Lookup ref should contain 2 elements"
25
+ [:name 1 2] #"Lookup ref should contain 2 elements"
26
+ [:age 10] #"Lookup ref attribute should be marked as :db/unique")))
27
+
28
+ (deftest test-lookup-refs-transact
29
+ (let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/identity}
30
+ :friend {:db/valueType :db.type/ref}})
31
+ [{:db/id 1 :name "Ivan"}
32
+ {:db/id 2 :name "Petr"}])]
33
+ (are [tx res] (= res (tdc/entity-map (d/db-with db tx) 1))
34
+ ;; Additions
35
+ [[:db/add [:name "Ivan"] :age 35]]
36
+ {:db/id 1 :name "Ivan" :age 35}
37
+
38
+ [{:db/id [:name "Ivan"] :age 35}]
39
+ {:db/id 1 :name "Ivan" :age 35}
40
+
41
+ [[:db/add 1 :friend [:name "Petr"]]]
42
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
43
+
44
+ [[:db/add 1 :friend [:name "Petr"]]]
45
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
46
+
47
+ [{:db/id 1 :friend [:name "Petr"]}]
48
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
49
+
50
+ [{:db/id 2 :_friend [:name "Ivan"]}]
51
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
52
+
53
+ ;; lookup refs are resolved at intermediate DB value
54
+ [[:db/add 3 :name "Oleg"]
55
+ [:db/add 1 :friend [:name "Oleg"]]]
56
+ {:db/id 1 :name "Ivan" :friend {:db/id 3}}
57
+
58
+ ;; CAS
59
+ [[:db.fn/cas [:name "Ivan"] :name "Ivan" "Oleg"]]
60
+ {:db/id 1 :name "Oleg"}
61
+
62
+ [[:db/add 1 :friend 1]
63
+ [:db.fn/cas 1 :friend [:name "Ivan"] 2]]
64
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
65
+
66
+ [[:db/add 1 :friend 1]
67
+ [:db.fn/cas 1 :friend 1 [:name "Petr"]]]
68
+ {:db/id 1 :name "Ivan" :friend {:db/id 2}}
69
+
70
+ ;; Retractions
71
+ [[:db/add 1 :age 35]
72
+ [:db/retract [:name "Ivan"] :age 35]]
73
+ {:db/id 1 :name "Ivan"}
74
+
75
+ [[:db/add 1 :friend 2]
76
+ [:db/retract 1 :friend [:name "Petr"]]]
77
+ {:db/id 1 :name "Ivan"}
78
+
79
+ [[:db/add 1 :age 35]
80
+ [:db.fn/retractAttribute [:name "Ivan"] :age]]
81
+ {:db/id 1 :name "Ivan"}
82
+
83
+ [[:db.fn/retractEntity [:name "Ivan"]]]
84
+ {:db/id 1})
85
+
86
+ (are [tx msg] (thrown-with-msg? Throwable msg (d/db-with db tx))
87
+ [{:db/id [:name "Oleg"], :age 10}]
88
+ #"Nothing found for entity id"
89
+
90
+ [[:db/add [:name "Oleg"] :age 10]]
91
+ #"Nothing found for entity id")))
92
+
93
+ (deftest test-lookup-refs-transact-multi
94
+ (let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/identity}
95
+ :friends {:db/valueType :db.type/ref
96
+ :db/cardinality :db.cardinality/many}})
97
+ [{:db/id 1 :name "Ivan"}
98
+ {:db/id 2 :name "Petr"}
99
+ {:db/id 3 :name "Oleg"}
100
+ {:db/id 4 :name "Sergey"}])]
101
+ (are [tx res] (= (tdc/entity-map (d/db-with db tx) 1) res)
102
+ ;; Additions
103
+ [[:db/add 1 :friends [:name "Petr"]]]
104
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}}
105
+
106
+ [[:db/add 1 :friends [:name "Petr"]]
107
+ [:db/add 1 :friends [:name "Oleg"]]]
108
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2} {:db/id 3}}}
109
+
110
+ [{:db/id 1 :friends [:name "Petr"]}]
111
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}}
112
+
113
+ [{:db/id 1 :friends [[:name "Petr"]]}]
114
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}}
115
+
116
+ [{:db/id 1 :friends [[:name "Petr"] [:name "Oleg"]]}]
117
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2} {:db/id 3}}}
118
+
119
+ [{:db/id 1 :friends [2 [:name "Oleg"]]}]
120
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2} {:db/id 3}}}
121
+
122
+ [{:db/id 1 :friends [[:name "Petr"] 3]}]
123
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2} {:db/id 3}}}
124
+
125
+ ;; reverse refs
126
+ [{:db/id 2 :_friends [:name "Ivan"]}]
127
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}}
128
+
129
+ [{:db/id 2 :_friends [[:name "Ivan"]]}]
130
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}}
131
+
132
+ [{:db/id 2 :_friends [[:name "Ivan"] [:name "Oleg"]]}]
133
+ {:db/id 1 :name "Ivan" :friends #{{:db/id 2}}})))
134
+
135
+ (deftest lookup-refs-index-access
136
+ (let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/identity}
137
+ :friends {:db/valueType :db.type/ref
138
+ :db/cardinality :db.cardinality/many}})
139
+ [{:db/id 1 :name "Ivan" :friends [2 3]}
140
+ {:db/id 2 :name "Petr" :friends 3}
141
+ {:db/id 3 :name "Oleg"}])]
142
+ (are [index attrs datoms] (= (map (juxt :e :a :v) (apply d/datoms db index attrs)) datoms)
143
+ :eavt [[:name "Ivan"]]
144
+ [[1 :friends 2] [1 :friends 3] [1 :name "Ivan"]]
145
+
146
+ :eavt [[:name "Ivan"] :friends]
147
+ [[1 :friends 2] [1 :friends 3]]
148
+
149
+ :eavt [[:name "Ivan"] :friends [:name "Petr"]]
150
+ [[1 :friends 2]]
151
+
152
+ :aevt [:friends [:name "Ivan"]]
153
+ [[1 :friends 2] [1 :friends 3]]
154
+
155
+ :aevt [:friends [:name "Ivan"] [:name "Petr"]]
156
+ [[1 :friends 2]]
157
+
158
+ :avet [:friends [:name "Oleg"]]
159
+ [[1 :friends 3] [2 :friends 3]]
160
+
161
+ :avet [:friends [:name "Oleg"] [:name "Ivan"]]
162
+ [[1 :friends 3]])
163
+
164
+ (are [index attrs resolved-attrs] (= (vec (apply d/seek-datoms db index attrs))
165
+ (vec (apply d/seek-datoms db index resolved-attrs)))
166
+ :eavt [[:name "Ivan"]] [1]
167
+ :eavt [[:name "Ivan"] :name] [1 :name]
168
+ :eavt [[:name "Ivan"] :friends [:name "Oleg"]] [1 :friends 3]
169
+
170
+ :aevt [:friends [:name "Petr"]] [:friends 2]
171
+ :aevt [:friends [:name "Ivan"] [:name "Oleg"]] [:friends 1 3]
172
+
173
+ :avet [:friends [:name "Oleg"]] [:friends 3]
174
+ :avet [:friends [:name "Oleg"] [:name "Petr"]] [:friends 3 2])
175
+
176
+ (are [attr start end datoms] (= (map (juxt :e :a :v) (d/index-range db {:attrid attr :start start :end end})) datoms)
177
+ :friends [:name "Oleg"] [:name "Oleg"]
178
+ [[1 :friends 3] [2 :friends 3]]
179
+
180
+ :friends [:name "Petr"] [:name "Petr"]
181
+ [[1 :friends 2]]
182
+
183
+ :friends [:name "Petr"] [:name "Oleg"]
184
+ [[1 :friends 2] [1 :friends 3] [2 :friends 3]])))
185
+
186
+ (deftest test-lookup-refs-query
187
+ (let [schema {:name {:db/unique :db.unique/identity}
188
+ :friend {:db/valueType :db.type/ref}}
189
+ db (d/db-with (db/empty-db schema)
190
+ [{:db/id 1 :id 1 :name "Ivan" :age 11 :friend 2}
191
+ {:db/id 2 :id 2 :name "Petr" :age 22 :friend 3}
192
+ {:db/id 3 :id 3 :name "Oleg" :age 33}])]
193
+ (is (= (set (d/q '[:find ?e ?v
194
+ :in $ ?e
195
+ :where [?e :age ?v]]
196
+ db [:name "Ivan"]))
197
+ #{[[:name "Ivan"] 11]}))
198
+
199
+ (is (= (set (d/q '[:find [?v ...]
200
+ :in $ [?e ...]
201
+ :where [?e :age ?v]]
202
+ db [[:name "Ivan"] [:name "Petr"]]))
203
+ #{11 22}))
204
+
205
+ (is (= (set (d/q '[:find [?e ...]
206
+ :in $ ?v
207
+ :where [?e :friend ?v]]
208
+ db [:name "Petr"]))
209
+ #{1}))
210
+
211
+ (is (= (set (d/q '[:find [?e ...]
212
+ :in $ [?v ...]
213
+ :where [?e :friend ?v]]
214
+ db [[:name "Petr"] [:name "Oleg"]]))
215
+ #{1 2}))
216
+
217
+ (is (= (d/q '[:find ?e ?v
218
+ :in $ ?e ?v
219
+ :where [?e :friend ?v]]
220
+ db [:name "Ivan"] [:name "Petr"])
221
+ #{[[:name "Ivan"] [:name "Petr"]]}))
222
+
223
+ (is (= (d/q '[:find ?e ?v
224
+ :in $ [?e ...] [?v ...]
225
+ :where [?e :friend ?v]]
226
+ db [[:name "Ivan"] [:name "Petr"] [:name "Oleg"]]
227
+ [[:name "Ivan"] [:name "Petr"] [:name "Oleg"]])
228
+ #{[[:name "Ivan"] [:name "Petr"]]
229
+ [[:name "Petr"] [:name "Oleg"]]}))
230
+
231
+ (is (= (d/q '[:find ?e
232
+ :in $ [?e ...]
233
+ :where [?e :friend 3]]
234
+ db [1 2 3 "A"])
235
+ #{[2]}))
236
+
237
+ (let [db2 (d/db-with (db/empty-db schema)
238
+ [{:db/id 3 :name "Ivan" :id 3}
239
+ {:db/id 1 :name "Petr" :id 1}
240
+ {:db/id 2 :name "Oleg" :id 2}])]
241
+ (is (= (d/q '[:find ?e ?e1 ?e2
242
+ :in $1 $2 [?e ...]
243
+ :where [$1 ?e :id ?e1]
244
+ [$2 ?e :id ?e2]]
245
+ db db2 [[:name "Ivan"] [:name "Petr"] [:name "Oleg"]])
246
+ #{[[:name "Ivan"] 1 3]
247
+ [[:name "Petr"] 2 1]
248
+ [[:name "Oleg"] 3 2]})))
249
+
250
+ (testing "inline refs"
251
+ (is (= (d/q '[:find ?v
252
+ :where [[:name "Ivan"] :friend ?v]]
253
+ db)
254
+ #{[2]}))
255
+
256
+ (is (= (d/q '[:find ?e
257
+ :where [?e :friend [:name "Petr"]]]
258
+ db)
259
+ #{[1]}))
260
+
261
+ (is (thrown-with-msg? Throwable #"Nothing found for entity id"
262
+ (d/q '[:find ?e
263
+ :where [[:name "Valery"] :friend ?e]]
264
+ db))))))
265
+
266
+
@@ -0,0 +1,27 @@
1
+ (ns datahike.test.lru-test
2
+ (:require
3
+ #?(:cljs [cljs.test :as t :refer-macros [are deftest]]
4
+ :clj [clojure.test :as t :refer [are deftest]])
5
+ [datahike.lru :as lru]))
6
+
7
+ (deftest test-lru
8
+ (let [l0 (lru/lru 2)
9
+ l1 (assoc l0 :a 1)
10
+ l2 (assoc l1 :b 2)
11
+ l3 (assoc l2 :c 3)
12
+ l4 (assoc l3 :b 4)
13
+ l5 (assoc l4 :d 5)]
14
+ (are [l k v] (= (get l k) v)
15
+ l0 :a nil
16
+ l1 :a 1
17
+ l2 :a 1
18
+ l2 :b 2
19
+ l3 :a nil ;; :a get evicted on third insert
20
+ l3 :b 2
21
+ l3 :c 3
22
+ l4 :b 2 ;; assoc updates access time, but does not change a value
23
+ l4 :c 3
24
+ l5 :b 2 ;; :b remains
25
+ l5 :c nil ;; :c gets evicted as the oldest one
26
+ l5 :d 5)))
27
+
@@ -0,0 +1,297 @@
1
+ (ns datahike.test.migrate-test
2
+ (:require [clojure.test :refer :all]
3
+ [datahike.api :as d]
4
+ [datahike.datom :as datom]
5
+ [datahike.migrate :as m]
6
+ [datahike.db.utils :as dbu]
7
+ [datahike.test.utils :as utils]))
8
+
9
+ (def tx-data [[:db/add 1 :db/cardinality :db.cardinality/one 536870913 true]
10
+ [:db/add 1 :db/ident :name 536870913 true]
11
+ [:db/add 1 :db/index true 536870913 true]
12
+ [:db/add 1 :db/unique :db.unique/identity 536870913 true]
13
+ [:db/add 1 :db/valueType :db.type/string 536870913 true]
14
+ [:db/add 2 :db/cardinality :db.cardinality/one 536870913 true]
15
+ [:db/add 2 :db/ident :age 536870913 true]
16
+ [:db/add 2 :db/valueType :db.type/long 536870913 true]
17
+ [:db/add 3 :age 25 536870913 true]
18
+ [:db/add 3 :name "Alice" 536870913 true]
19
+ [:db/add 4 :age 35 536870913 true]
20
+ [:db/add 4 :name "Bob" 536870913 true]])
21
+
22
+ (def tx-meta [[:db/ident :db.install/attribute 536870912 true]
23
+ [:db/doc "An attribute's cardinality" 536870912 true]
24
+ [:db/valueType 28 536870912 true]
25
+ [:db/ident :db.type/instant 536870912 true]
26
+ [:db/ident :db.type/bigint 536870912 true]
27
+ [:db/cardinality 11 536870912 true]
28
+ [:db/ident :db/txInstant 536870912 true]
29
+ [:db/ident :db/isComponent 536870912 true]
30
+ [:db/ident :db/unique 536870912 true]
31
+ [:db/ident :db/valueType 536870912 true]
32
+ [:db/valueType 26 536870912 true]
33
+ [:db/ident :db.type/valueType 536870912 true]
34
+ [:db/ident :db.type/unique 536870912 true]
35
+ [:db/ident :db.part/tx 536870912 true]
36
+ [:db/ident :db/tupleAttrs 536870912 true]
37
+ [:db/doc "An attribute's unique selection" 536870912 true]
38
+ [:db/doc "An attribute's history selection" 536870912 true]
39
+ [:db/txInstant #inst "1970-01-01T00:00:00.000-00:00" 536870912 true]
40
+ [:db/ident :db.type/boolean 536870912 true]
41
+ [:db/valueType 31 536870912 true]
42
+ [:db/ident :db/noHistory 536870912 true]
43
+ [:db/valueType 17 536870912 true]
44
+ [:db/ident :db.type/float 536870912 true]
45
+ [:db/ident :db.part/sys 536870912 true]
46
+ [:db/ident :db/index 536870912 true]
47
+ [:db/noHistory true 536870912 true]
48
+ [:db/ident :db.part/user 536870912 true]
49
+ [:db/ident :db.type/tuple 536870912 true]
50
+ [:db/ident :db/doc 536870912 true]
51
+ [:db/ident :db/tupleType 536870912 true]
52
+ [:db/doc
53
+ "An attribute's or specification's identifier"
54
+ 536870912
55
+ true]
56
+ [:db/ident :db.type/uuid 536870912 true]
57
+ [:db/doc "Only for interoperability with Datomic" 536870912 true]
58
+ [:db/ident :db.type/cardinality 536870912 true]
59
+ [:db/valueType 30 536870912 true]
60
+ [:db/ident :db/cardinality 536870912 true]
61
+ [:db/ident :db.cardinality/one 536870912 true]
62
+ [:db/ident :db.unique/identity 536870912 true]
63
+ [:db/valueType 23 536870912 true]
64
+ [:db/ident :db.type/number 536870912 true]
65
+ [:db/unique 33 536870912 true] [:db/ident :db/ident 536870912 true]
66
+ [:db/ident :db.type/ref 536870912 true]
67
+ [:db/ident :db.type/bigdec 536870912 true]
68
+ [:db/ident :db/tupleTypes 536870912 true]
69
+ [:db/ident :db.type/symbol 536870912 true]
70
+ [:db/valueType 22 536870912 true]
71
+ [:db/doc "An attribute's index selection" 536870912 true]
72
+ [:db/doc "A transaction's time-point" 536870912 true]
73
+ [:db/index true 536870912 true]
74
+ [:db/ident :db.type.install/attribute 536870912 true]
75
+ [:db/ident :db.unique/value 536870912 true]
76
+ [:db/valueType 19 536870912 true]
77
+ [:db/ident :db.type/long 536870912 true]
78
+ [:db/ident :db.cardinality/many 536870912 true]
79
+ [:db/ident :db.type/string 536870912 true]
80
+ [:db/ident :db.type/double 536870912 true]
81
+ [:db/doc "An attribute's value type" 536870912 true]
82
+ [:db/doc "An attribute's documentation" 536870912 true]
83
+ [:db/ident :db.type/keyword 536870912 true]])
84
+
85
+ (deftest export-import-test
86
+ (let [os-prefix (case (System/getProperty "os.name")
87
+ "Windows 10" (System/getProperty "java.io.tmpdir")
88
+ "/tmp/")
89
+ old-path (str os-prefix "old-db")
90
+ new-path (str os-prefix "new-db")
91
+ export-path (str os-prefix "eavt-dump")
92
+ base-config {:store {:backend :file}
93
+ :schema-flexibility :write
94
+ :keep-history? false
95
+ :attribute-refs? false}
96
+ add-uuid (fn [cfg] (assoc-in cfg [:store :id] (java.util.UUID/randomUUID)))
97
+ schema [{:db/ident :name
98
+ :db/cardinality :db.cardinality/one
99
+ :db/index true
100
+ :db/unique :db.unique/identity
101
+ :db/valueType :db.type/string}
102
+ {:db/ident :parents
103
+ :db/cardinality :db.cardinality/many
104
+ :db/valueType :db.type/ref}
105
+ {:db/ident :age
106
+ :db/cardinality :db.cardinality/one
107
+ :db/valueType :db.type/long}]
108
+ tx-data {:tx-data [{:name "Alice" :age 25}
109
+ {:name "Bob" :age 35}
110
+ {:name "Charlie"
111
+ :age 5
112
+ :parents [[:name "Alice"] [:name "Bob"]]}
113
+ {:name "Daisy" :age 20}
114
+ {:name "Erhard" :age 20}]}]
115
+
116
+ (testing "Same configuration roundtrip for exporting and importing."
117
+ (doseq [hist [true false]
118
+ attr-ref [true false]]
119
+ (let [cfg (merge base-config
120
+ {:keep-history? hist
121
+ :attribute-refs? attr-ref})
122
+ old-cfg (add-uuid (assoc-in cfg [:store :path] (str old-path (utils/get-time))))
123
+ old-conn (utils/setup-db old-cfg)
124
+ new-cfg (add-uuid (assoc-in cfg [:store :path] (str new-path (utils/get-time))))
125
+ new-conn (utils/setup-db new-cfg)]
126
+ (d/transact old-conn schema)
127
+ (d/transact old-conn tx-data)
128
+ (d/transact old-conn {:tx-data [[:db/retractEntity [:name "Erhard"]]]})
129
+ (m/export-db old-conn export-path)
130
+ (m/import-db new-conn export-path)
131
+ (is (= (d/datoms (if (:keep-history? cfg) (d/history @old-conn) @old-conn) :eavt)
132
+ (filter #(< (:e %) (:max-tx @new-conn))
133
+ (d/datoms (if (:keep-history? cfg) (d/history @new-conn) @new-conn) :eavt))))
134
+ (d/release old-conn)
135
+ (d/release new-conn)
136
+ (d/delete-database old-cfg)
137
+ (d/delete-database new-cfg))))
138
+
139
+ (testing "Export history database, import non-history database"
140
+ (let [old-cfg (-> base-config
141
+ (assoc-in [:store :path] (str old-path (utils/get-time)))
142
+ (assoc :keep-history? true)
143
+ add-uuid)
144
+ old-conn (utils/setup-db old-cfg)
145
+ new-cfg (-> base-config
146
+ (assoc-in [:store :path] (str new-path (utils/get-time)))
147
+ (assoc :keep-history? false)
148
+ add-uuid)
149
+ new-conn (utils/setup-db new-cfg)]
150
+ (d/transact old-conn schema)
151
+ (d/transact old-conn tx-data)
152
+ (m/export-db old-conn export-path)
153
+ (m/import-db new-conn export-path)
154
+ (is (= (d/datoms @old-conn :eavt)
155
+ (d/datoms @new-conn :eavt)))
156
+ (d/release old-conn)
157
+ (d/release new-conn)
158
+ (d/delete-database old-cfg)
159
+ (d/delete-database new-cfg)))
160
+
161
+ (testing "Export non-history database, import history database"
162
+ (let [old-cfg (-> base-config
163
+ (assoc-in [:store :path] (str old-path (utils/get-time)))
164
+ (assoc :keep-history? false)
165
+ add-uuid)
166
+ old-conn (utils/setup-db old-cfg)
167
+ new-cfg (-> base-config
168
+ (assoc-in [:store :path] (str new-path (utils/get-time)))
169
+ (assoc :keep-history? true)
170
+ add-uuid)
171
+ new-conn (utils/setup-db new-cfg)]
172
+ (d/transact old-conn schema)
173
+ (d/transact old-conn tx-data)
174
+ (m/export-db old-conn export-path)
175
+ (m/import-db new-conn export-path)
176
+ (is (= (d/datoms @old-conn :eavt)
177
+ (filter #(< (:e %) (:max-tx @new-conn))
178
+ (d/datoms @new-conn :eavt))))
179
+ (d/release old-conn)
180
+ (d/release new-conn)
181
+ (d/delete-database old-cfg)
182
+ (d/delete-database new-cfg)))))
183
+
184
+ (deftest load-entities-test
185
+ (testing "Test migrate simple datoms without attribute refs"
186
+ (let [source-datoms (->> tx-data
187
+ (mapv #(-> % rest vec))
188
+ (concat [[536870913 :db/txInstant #inst "2020-03-11T14:54:27.979-00:00" 536870913 true]]))
189
+ cfg {:store {:backend :memory
190
+ :id #uuid "001d0000-0000-0000-0000-00000000001d"}
191
+ :keep-history? true
192
+ :attribute-refs false}
193
+ conn (utils/setup-db cfg)]
194
+ @(d/load-entities conn source-datoms)
195
+ (is (= (into #{} source-datoms)
196
+ (d/q '[:find ?e ?a ?v ?t ?op :where [?e ?a ?v ?t ?op]] @conn)))
197
+ (d/release conn)))
198
+ (testing "Test migrate simple datoms with attribute refs"
199
+ (let [source-datoms (->> tx-data
200
+ (mapv #(-> % rest vec))
201
+ (concat [[536870913 :db/txInstant #inst "2020-03-11T14:54:27.979-00:00" 536870913 true]]))
202
+ cfg {:store {:backend :memory
203
+ :id #uuid "001e0000-0000-0000-0000-00000000001e"}
204
+ :keep-history? true
205
+ :attribute-refs? true
206
+ :schema-flexibility :write}
207
+ conn (utils/setup-db cfg)]
208
+ @(d/load-entities conn source-datoms)
209
+ (is (= (into #{} (->> source-datoms
210
+ (mapv (comp vec rest))
211
+ (concat tx-meta)))
212
+ (d/q '[:find ?a ?v ?t ?op
213
+ :where
214
+ [?e ?attr ?v ?t ?op]
215
+ [?attr :db/ident ?a]] @conn)))
216
+ (d/release conn))))
217
+
218
+ (deftest load-entities-history-test
219
+ (testing "Migrate predefined set with historical data"
220
+ (let [source-cfg {:store {:backend :memory
221
+ :id #uuid "001f0000-0000-0000-0000-00000000001f"}
222
+ :name "load-entities-history-test-source"
223
+ :keep-history? true
224
+ :schema-flexibility :write
225
+ :search-cache-size 0
226
+ :store-cache-size 1
227
+ :attribute-refs? false}
228
+ schema [{:db/ident :name
229
+ :db/cardinality :db.cardinality/one
230
+ :db/index true
231
+ :db/unique :db.unique/identity
232
+ :db/valueType :db.type/string}]
233
+ source-conn (utils/setup-db source-cfg)
234
+ txs [schema
235
+ [{:name "Alice"} {:name "Bob"}]
236
+ [{:name "Charlie"} {:name "Daisy"}]
237
+ [[:db/retractEntity [:name "Alice"]]]]
238
+ _ (doseq [tx-data txs]
239
+ (d/transact source-conn {:tx-data tx-data}))
240
+ datoms-to-export (d/datoms (d/history @source-conn) :eavt)
241
+
242
+ ;; The datoms to export must primarily
243
+ ;; be sorted by transaction entity id
244
+ ;; and secondarily so that datoms with attribute `:db/txInstant`
245
+ ;; come before other datoms
246
+ export-data (->> datoms-to-export
247
+ (map (comp vec seq))
248
+ (sort-by (fn [[e a v tx]]
249
+ [tx
250
+
251
+ ;; TODO: It seems as if :db/txInstant
252
+ ;; datoms must come first. Is this a bug
253
+ ;; in load-entities?
254
+ (case a
255
+ :db/txInstant 0
256
+ 1)]))
257
+ (into []))
258
+ target-cfg (-> source-cfg
259
+ (assoc-in [:store :id] #uuid "00200000-0000-0000-0000-000000000020")
260
+ (assoc-in [:name] "load-entities-history-test-target"))
261
+ target-conn (utils/setup-db target-cfg)
262
+ _ @(d/load-entities target-conn export-data)
263
+ current-q (fn [conn] (d/q
264
+ '[:find ?n
265
+ :where
266
+ [?e :name ?n]]
267
+ @conn))
268
+ history-q (fn [conn] (d/q '[:find ?n ?t ?op
269
+ :where
270
+ [?e :name ?n ?t ?op]]
271
+ (d/history @conn)))]
272
+ (is (dbu/distinct-sorted-datoms? :eavt datoms-to-export))
273
+ (is (= (current-q source-conn)
274
+ (current-q target-conn)))
275
+ (is (= (history-q source-conn)
276
+ (history-q target-conn)))
277
+ (d/release source-conn)
278
+ (d/release target-conn))))
279
+
280
+ (deftest test-binary-support
281
+ (let [config {:store {:backend :memory
282
+ :id #uuid "00210000-0000-0000-0000-000000000021"}
283
+ :schema-flexibility :read
284
+ :keep-history? false}
285
+ export-path "/tmp/test-export-binary-support"
286
+ conn (utils/setup-db config)
287
+ import-conn (utils/setup-db)]
288
+ (d/transact conn [{:db/id 1, :name "Jiayi", :payload (byte-array [0 2 3])}
289
+ {:db/id 2, :name "Peter", :payload (byte-array [1 2 3])}])
290
+ (m/export-db conn export-path)
291
+ (m/import-db import-conn export-path)
292
+ (is (utils/all-true? (map #(or (= %1 %2) (utils/all-eq? (nth %1 2) (nth %2 2)))
293
+ (d/datoms @conn :eavt)
294
+ (filter #(< (datom/datom-tx %) (:max-tx @import-conn))
295
+ (d/datoms @import-conn :eavt)))))
296
+ (d/release conn)
297
+ (d/release import-conn)))