mdbxmou 0.1.26

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 (220) hide show
  1. package/.github/workflows/ci.yml +32 -0
  2. package/.github/workflows/publish.yml +27 -0
  3. package/.gitmodules +3 -0
  4. package/CMakeLists.txt +53 -0
  5. package/LICENSE +201 -0
  6. package/README.md +639 -0
  7. package/build.js +11 -0
  8. package/deps/libmdbx/.clang-format +3 -0
  9. package/deps/libmdbx/.cmake-format.yaml +3 -0
  10. package/deps/libmdbx/.le.ini +40 -0
  11. package/deps/libmdbx/CMakeLists.txt +1269 -0
  12. package/deps/libmdbx/COPYRIGHT +159 -0
  13. package/deps/libmdbx/ChangeLog.md +2786 -0
  14. package/deps/libmdbx/GNUmakefile +950 -0
  15. package/deps/libmdbx/LICENSE +177 -0
  16. package/deps/libmdbx/Makefile +16 -0
  17. package/deps/libmdbx/NOTICE +39 -0
  18. package/deps/libmdbx/README.md +863 -0
  19. package/deps/libmdbx/TODO.md +43 -0
  20. package/deps/libmdbx/cmake/compiler.cmake +1221 -0
  21. package/deps/libmdbx/cmake/profile.cmake +58 -0
  22. package/deps/libmdbx/cmake/utils.cmake +524 -0
  23. package/deps/libmdbx/conanfile.py +323 -0
  24. package/deps/libmdbx/docs/Doxyfile.in +2734 -0
  25. package/deps/libmdbx/docs/_preface.md +47 -0
  26. package/deps/libmdbx/docs/_restrictions.md +248 -0
  27. package/deps/libmdbx/docs/_starting.md +245 -0
  28. package/deps/libmdbx/docs/_toc.md +34 -0
  29. package/deps/libmdbx/docs/header.html +96 -0
  30. package/deps/libmdbx/example/CMakeLists.txt +6 -0
  31. package/deps/libmdbx/example/README.md +1 -0
  32. package/deps/libmdbx/example/example-mdbx.c +154 -0
  33. package/deps/libmdbx/example/sample-bdb.txt +77 -0
  34. package/deps/libmdbx/mdbx.h +6655 -0
  35. package/deps/libmdbx/mdbx.h++ +6428 -0
  36. package/deps/libmdbx/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +173 -0
  37. package/deps/libmdbx/src/alloy.c +54 -0
  38. package/deps/libmdbx/src/api-cold.c +543 -0
  39. package/deps/libmdbx/src/api-copy.c +912 -0
  40. package/deps/libmdbx/src/api-cursor.c +754 -0
  41. package/deps/libmdbx/src/api-dbi.c +315 -0
  42. package/deps/libmdbx/src/api-env.c +1434 -0
  43. package/deps/libmdbx/src/api-extra.c +165 -0
  44. package/deps/libmdbx/src/api-key-transform.c +197 -0
  45. package/deps/libmdbx/src/api-misc.c +286 -0
  46. package/deps/libmdbx/src/api-opts.c +575 -0
  47. package/deps/libmdbx/src/api-range-estimate.c +365 -0
  48. package/deps/libmdbx/src/api-txn-data.c +454 -0
  49. package/deps/libmdbx/src/api-txn.c +921 -0
  50. package/deps/libmdbx/src/atomics-ops.h +364 -0
  51. package/deps/libmdbx/src/atomics-types.h +97 -0
  52. package/deps/libmdbx/src/audit.c +109 -0
  53. package/deps/libmdbx/src/bits.md +34 -0
  54. package/deps/libmdbx/src/chk.c +1796 -0
  55. package/deps/libmdbx/src/cogs.c +309 -0
  56. package/deps/libmdbx/src/cogs.h +506 -0
  57. package/deps/libmdbx/src/coherency.c +170 -0
  58. package/deps/libmdbx/src/config.h.in +88 -0
  59. package/deps/libmdbx/src/cursor.c +2396 -0
  60. package/deps/libmdbx/src/cursor.h +391 -0
  61. package/deps/libmdbx/src/dbi.c +717 -0
  62. package/deps/libmdbx/src/dbi.h +142 -0
  63. package/deps/libmdbx/src/debug_begin.h +36 -0
  64. package/deps/libmdbx/src/debug_end.h +15 -0
  65. package/deps/libmdbx/src/dpl.c +486 -0
  66. package/deps/libmdbx/src/dpl.h +134 -0
  67. package/deps/libmdbx/src/dxb.c +1335 -0
  68. package/deps/libmdbx/src/env.c +607 -0
  69. package/deps/libmdbx/src/essentials.h +125 -0
  70. package/deps/libmdbx/src/gc-get.c +1345 -0
  71. package/deps/libmdbx/src/gc-put.c +970 -0
  72. package/deps/libmdbx/src/gc.h +40 -0
  73. package/deps/libmdbx/src/global.c +474 -0
  74. package/deps/libmdbx/src/internals.h +585 -0
  75. package/deps/libmdbx/src/layout-dxb.h +288 -0
  76. package/deps/libmdbx/src/layout-lck.h +289 -0
  77. package/deps/libmdbx/src/lck-posix.c +859 -0
  78. package/deps/libmdbx/src/lck-windows.c +607 -0
  79. package/deps/libmdbx/src/lck.c +174 -0
  80. package/deps/libmdbx/src/lck.h +110 -0
  81. package/deps/libmdbx/src/logging_and_debug.c +250 -0
  82. package/deps/libmdbx/src/logging_and_debug.h +159 -0
  83. package/deps/libmdbx/src/man1/mdbx_chk.1 +106 -0
  84. package/deps/libmdbx/src/man1/mdbx_copy.1 +95 -0
  85. package/deps/libmdbx/src/man1/mdbx_drop.1 +48 -0
  86. package/deps/libmdbx/src/man1/mdbx_dump.1 +101 -0
  87. package/deps/libmdbx/src/man1/mdbx_load.1 +105 -0
  88. package/deps/libmdbx/src/man1/mdbx_stat.1 +86 -0
  89. package/deps/libmdbx/src/mdbx.c++ +1837 -0
  90. package/deps/libmdbx/src/meta.c +656 -0
  91. package/deps/libmdbx/src/meta.h +168 -0
  92. package/deps/libmdbx/src/mvcc-readers.c +414 -0
  93. package/deps/libmdbx/src/node.c +365 -0
  94. package/deps/libmdbx/src/node.h +102 -0
  95. package/deps/libmdbx/src/ntdll.def +1246 -0
  96. package/deps/libmdbx/src/options.h +534 -0
  97. package/deps/libmdbx/src/osal.c +3485 -0
  98. package/deps/libmdbx/src/osal.h +587 -0
  99. package/deps/libmdbx/src/page-get.c +483 -0
  100. package/deps/libmdbx/src/page-iov.c +185 -0
  101. package/deps/libmdbx/src/page-iov.h +34 -0
  102. package/deps/libmdbx/src/page-ops.c +744 -0
  103. package/deps/libmdbx/src/page-ops.h +142 -0
  104. package/deps/libmdbx/src/pnl.c +236 -0
  105. package/deps/libmdbx/src/pnl.h +146 -0
  106. package/deps/libmdbx/src/preface.h +990 -0
  107. package/deps/libmdbx/src/proto.h +105 -0
  108. package/deps/libmdbx/src/refund.c +212 -0
  109. package/deps/libmdbx/src/sort.h +484 -0
  110. package/deps/libmdbx/src/spill.c +431 -0
  111. package/deps/libmdbx/src/spill.h +74 -0
  112. package/deps/libmdbx/src/table.c +107 -0
  113. package/deps/libmdbx/src/tls.c +551 -0
  114. package/deps/libmdbx/src/tls.h +43 -0
  115. package/deps/libmdbx/src/tools/chk.c +673 -0
  116. package/deps/libmdbx/src/tools/copy.c +166 -0
  117. package/deps/libmdbx/src/tools/drop.c +199 -0
  118. package/deps/libmdbx/src/tools/dump.c +515 -0
  119. package/deps/libmdbx/src/tools/load.c +831 -0
  120. package/deps/libmdbx/src/tools/stat.c +516 -0
  121. package/deps/libmdbx/src/tools/wingetopt.c +87 -0
  122. package/deps/libmdbx/src/tools/wingetopt.h +30 -0
  123. package/deps/libmdbx/src/tree-ops.c +1554 -0
  124. package/deps/libmdbx/src/tree-search.c +140 -0
  125. package/deps/libmdbx/src/txl.c +99 -0
  126. package/deps/libmdbx/src/txl.h +26 -0
  127. package/deps/libmdbx/src/txn.c +1083 -0
  128. package/deps/libmdbx/src/unaligned.h +205 -0
  129. package/deps/libmdbx/src/utils.c +32 -0
  130. package/deps/libmdbx/src/utils.h +76 -0
  131. package/deps/libmdbx/src/version.c.in +44 -0
  132. package/deps/libmdbx/src/walk.c +290 -0
  133. package/deps/libmdbx/src/walk.h +20 -0
  134. package/deps/libmdbx/src/windows-import.c +152 -0
  135. package/deps/libmdbx/src/windows-import.h +128 -0
  136. package/deps/libmdbx/test/CMakeLists.txt +317 -0
  137. package/deps/libmdbx/test/append.c++ +237 -0
  138. package/deps/libmdbx/test/base.h++ +92 -0
  139. package/deps/libmdbx/test/battery-tmux.sh +64 -0
  140. package/deps/libmdbx/test/cases.c++ +118 -0
  141. package/deps/libmdbx/test/chrono.c++ +134 -0
  142. package/deps/libmdbx/test/chrono.h++ +85 -0
  143. package/deps/libmdbx/test/config.c++ +643 -0
  144. package/deps/libmdbx/test/config.h++ +334 -0
  145. package/deps/libmdbx/test/copy.c++ +62 -0
  146. package/deps/libmdbx/test/dead.c++ +39 -0
  147. package/deps/libmdbx/test/dump-load.sh +40 -0
  148. package/deps/libmdbx/test/extra/crunched_delete.c++ +409 -0
  149. package/deps/libmdbx/test/extra/cursor_closing.c++ +410 -0
  150. package/deps/libmdbx/test/extra/dbi.c++ +229 -0
  151. package/deps/libmdbx/test/extra/doubtless_positioning.c++ +253 -0
  152. package/deps/libmdbx/test/extra/dupfix_addodd.c +94 -0
  153. package/deps/libmdbx/test/extra/dupfix_multiple.c++ +311 -0
  154. package/deps/libmdbx/test/extra/early_close_dbi.c++ +137 -0
  155. package/deps/libmdbx/test/extra/hex_base64_base58.c++ +118 -0
  156. package/deps/libmdbx/test/extra/maindb_ordinal.c++ +61 -0
  157. package/deps/libmdbx/test/extra/open.c++ +96 -0
  158. package/deps/libmdbx/test/extra/pcrf/README.md +2 -0
  159. package/deps/libmdbx/test/extra/pcrf/pcrf_test.c +380 -0
  160. package/deps/libmdbx/test/extra/probe.c++ +10 -0
  161. package/deps/libmdbx/test/extra/txn.c++ +407 -0
  162. package/deps/libmdbx/test/extra/upsert_alldups.c +193 -0
  163. package/deps/libmdbx/test/fork.c++ +263 -0
  164. package/deps/libmdbx/test/hill.c++ +447 -0
  165. package/deps/libmdbx/test/jitter.c++ +197 -0
  166. package/deps/libmdbx/test/keygen.c++ +393 -0
  167. package/deps/libmdbx/test/keygen.h++ +130 -0
  168. package/deps/libmdbx/test/log.c++ +358 -0
  169. package/deps/libmdbx/test/log.h++ +91 -0
  170. package/deps/libmdbx/test/main.c++ +706 -0
  171. package/deps/libmdbx/test/nested.c++ +318 -0
  172. package/deps/libmdbx/test/osal-unix.c++ +647 -0
  173. package/deps/libmdbx/test/osal-windows.c++ +440 -0
  174. package/deps/libmdbx/test/osal.h++ +41 -0
  175. package/deps/libmdbx/test/stochastic.sh +690 -0
  176. package/deps/libmdbx/test/stub/LICENSE +24 -0
  177. package/deps/libmdbx/test/stub/README.md +8 -0
  178. package/deps/libmdbx/test/stub/pthread_barrier.c +104 -0
  179. package/deps/libmdbx/test/stub/pthread_barrier.h +77 -0
  180. package/deps/libmdbx/test/test.c++ +1551 -0
  181. package/deps/libmdbx/test/test.h++ +298 -0
  182. package/deps/libmdbx/test/tmux.conf +3 -0
  183. package/deps/libmdbx/test/try.c++ +30 -0
  184. package/deps/libmdbx/test/ttl.c++ +240 -0
  185. package/deps/libmdbx/test/utils.c++ +203 -0
  186. package/deps/libmdbx/test/utils.h++ +326 -0
  187. package/deps/libmdbx/test/valgrind_suppress.txt +536 -0
  188. package/lib/mdbx_evn_async.js +211 -0
  189. package/lib/mdbx_worker.js +195 -0
  190. package/lib/nativemou.js +6 -0
  191. package/package.json +38 -0
  192. package/src/async/envmou_close.cpp +34 -0
  193. package/src/async/envmou_close.hpp +32 -0
  194. package/src/async/envmou_copy_to.cpp +29 -0
  195. package/src/async/envmou_copy_to.hpp +38 -0
  196. package/src/async/envmou_keys.cpp +201 -0
  197. package/src/async/envmou_keys.hpp +50 -0
  198. package/src/async/envmou_open.cpp +38 -0
  199. package/src/async/envmou_open.hpp +33 -0
  200. package/src/async/envmou_query.cpp +167 -0
  201. package/src/async/envmou_query.hpp +53 -0
  202. package/src/dbimou.cpp +522 -0
  203. package/src/dbimou.hpp +82 -0
  204. package/src/env_arg0.hpp +24 -0
  205. package/src/envmou.cpp +445 -0
  206. package/src/envmou.hpp +116 -0
  207. package/src/modulemou.cpp +113 -0
  208. package/src/querymou.cpp +177 -0
  209. package/src/querymou.hpp +93 -0
  210. package/src/txnmou.cpp +254 -0
  211. package/src/txnmou.hpp +122 -0
  212. package/src/typemou.hpp +239 -0
  213. package/src/valuemou.hpp +194 -0
  214. package/test/async.js +67 -0
  215. package/test/e3.js +38 -0
  216. package/test/e4.js +89 -0
  217. package/test/e5.js +162 -0
  218. package/test/test-batch-ops.js +243 -0
  219. package/test/test-cursor-mode.js +84 -0
  220. package/test/test-multi-mode.js +87 -0
package/test/e5.js ADDED
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+ const MDBX = require('../lib/nativemou.js');
5
+ const { MDBX_Env, MDBX_Param } = MDBX;
6
+
7
+ const test = async () => {
8
+ const path = 'e5';
9
+
10
+ await Promise.all([
11
+ fs.promises.rm(path, { recursive: true, force: true })
12
+ ]);
13
+
14
+ console.log("MDBX_Param:", MDBX_Param);
15
+ // получаем константы
16
+ const { keyMode, keyFlag, queryMode, valueFlag } = MDBX_Param;
17
+
18
+ const db = new MDBX_Env();
19
+
20
+ console.log('Opening database...');
21
+ const rc = await db.open({
22
+ path: path,
23
+ valueFlag: valueFlag.string
24
+ });
25
+
26
+ const count = 2;
27
+ console.log('Start write');
28
+ const txn = db.startWrite();
29
+ // будем использовать ordinal ключи
30
+ const dbi = txn.createMap(keyMode.ordinal);
31
+ for (let i = 0; i < count; i++) {
32
+ dbi.put(i, `val-${i}`, 0);
33
+ }
34
+ txn.commit();
35
+ console.log('Write finish');
36
+
37
+ // вычитаем key = 1 - асинхронно
38
+ // запишем при этом key = 2
39
+ // по умолчаниюю query выполняется в режиме wr
40
+ const out = await db.query([
41
+ {
42
+ mode: queryMode.get,
43
+ keyMode: keyMode.ordinal,
44
+ keyFlag: keyFlag.number,
45
+ item: [{ "key": 1 }, { "key": 42 }]
46
+ },
47
+ {
48
+ mode: queryMode.insertUnique,
49
+ keyMode: keyMode.ordinal,
50
+ keyFlag: keyFlag.number,
51
+ item: [{ "key": 2, "value":"val-2" }]
52
+ }
53
+ ]);
54
+ console.log('q1', JSON.stringify(out));
55
+
56
+ // вычитаем key = 2 - синхронно
57
+ const r = db.startRead();
58
+ const rdbi = r.openMap(keyMode.ordinal);
59
+ const keys = rdbi.keys();
60
+ const val = rdbi.get(2);
61
+ console.log("keys", keys);
62
+ console.log("read 2", val);
63
+
64
+ console.log("forEach");
65
+ rdbi.forEach((key, value, index) => {
66
+ console.log(`[${index}]`, key, value);
67
+ });
68
+
69
+ console.log("forEach from key 1");
70
+ rdbi.forEach(1, (key, value, index) => {
71
+ console.log(`[${index}]`, key, value);
72
+ });
73
+
74
+ {
75
+ const out = rdbi.keysFrom(1);
76
+ console.log("keysFrom()", out);
77
+ }
78
+
79
+ r.commit();
80
+
81
+ {
82
+ // почитаем асинхронно в упрощенном режиме
83
+ console.log("Read key = 2 in simple async mode to out2");
84
+ const out2 = await db.query({
85
+ keyMode: keyMode.ordinal,
86
+ item: [{ "key": 2 }, { "key": 42 }]
87
+ });
88
+ console.log("out2", JSON.stringify(out2));
89
+ }
90
+
91
+ {
92
+ // почитаем асинхронно в упрощенном режиме
93
+ const out = await db.keys({
94
+ keyMode: BigInt(keyMode.ordinal),
95
+ });
96
+ console.log("await keys()", out);
97
+ }
98
+
99
+ // добавим не существующий ключ
100
+ keys.push(42);
101
+ // удалим все ключи
102
+ const rm = await db.query([
103
+ {
104
+ mode: queryMode.del,
105
+ keyMode: keyMode.ordinal,
106
+ item: keys.map(key => ({ "key": key }))
107
+ }
108
+ ]);
109
+ console.log("rm keys", JSON.stringify(rm));
110
+
111
+ // Тестируем forEach с cursorMode
112
+ {
113
+ console.log("=== Testing forEach with cursorMode ===");
114
+
115
+ // добавим тестовые данные
116
+ const w = db.startWrite();
117
+ const wdbi = w.createMap(keyMode.ordinal);
118
+ for (let i = 1; i <= 10; i++) {
119
+ wdbi.put(i, `value${i}`);
120
+ }
121
+ w.commit();
122
+
123
+ // читаем заново
124
+ const r = db.startRead();
125
+ const dbi = r.openMap(keyMode.ordinal);
126
+
127
+ // forEach(fn) - обычный вызов
128
+ console.log("forEach(fn):");
129
+ dbi.forEach((k, v, i) => {
130
+ console.log(` ${i}: ${k} = ${v}`);
131
+ return i >= 2; // останавливаем после 3 элементов
132
+ });
133
+
134
+ // forEach(fromKey, fn) - с начального ключа
135
+ console.log("forEach(fromKey=5, fn):");
136
+ dbi.forEach(5, (k, v, i) => {
137
+ console.log(` ${i}: ${k} = ${v}`);
138
+ return i >= 2; // останавливаем после 3 элементов
139
+ });
140
+
141
+ // forEach(fromKey, cursorMode, fn) - с cursorMode
142
+ console.log("forEach(fromKey=7, cursorMode=keyGreater, fn):");
143
+ dbi.forEach(7, 'keyGreater', (k, v, i) => {
144
+ console.log(` ${i}: ${k} = ${v}`);
145
+ return i >= 1; // останавливаем после 2 элементов
146
+ });
147
+
148
+ r.commit();
149
+ }
150
+
151
+ // вычитаем все ключи
152
+ {
153
+ // вычитаем key = 2 - синхронно
154
+ const r = db.startRead();
155
+ const dbi = r.openMap(keyMode.ordinal);
156
+ console.log("keys", dbi.keys());
157
+ r.commit();
158
+ }
159
+ await db.close();
160
+ }
161
+
162
+ test().catch(console.error);
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ const fs = require("fs");
3
+ const { MDBX_Async_Env } = require("../lib/mdbx_evn_async.js");
4
+ const MDBX = require("../lib/nativemou.js");
5
+ const { MDBX_Param } = MDBX;
6
+
7
+ (async () => {
8
+ const testPath = "batch-ops-db";
9
+ await fs.promises.rm(testPath, { recursive: true, force: true }).catch(() => {});
10
+
11
+ const env = new MDBX_Async_Env();
12
+
13
+ try {
14
+ await env.open({ path: testPath });
15
+ const { keyMode } = MDBX_Param;
16
+
17
+ console.log("=== Тест групповых операций ===");
18
+
19
+ // 1. Создаем транзакцию
20
+ console.log("1. Создаем транзакцию записи...");
21
+ const w = await env.startWrite();
22
+ const dbi = await w.openMap({ keyMode: keyMode.ordinal, create: true });
23
+
24
+ // 2. Групповая запись множества ключей
25
+ console.log("2. Групповая запись 5 ключей...");
26
+ const itemsToWrite = [
27
+ { key: 1n, value: "value1" },
28
+ { key: 2n, value: "value2" },
29
+ { key: 3n, value: "value3" },
30
+ { key: 4n, value: "value4" },
31
+ { key: 5n, value: "value5" }
32
+ ];
33
+
34
+ const writeResults = await dbi.putBatch(itemsToWrite);
35
+ console.log("Результат записи:", writeResults);
36
+
37
+ // 3. Коммитим транзакцию
38
+ console.log("3. Коммитим транзакцию...");
39
+ await w.commit();
40
+
41
+ // 4. Создаем транзакцию чтения
42
+ console.log("4. Создаем транзакцию чтения...");
43
+ const r = await env.startRead();
44
+ const readDbi = await r.openMap({ keyMode: keyMode.ordinal });
45
+
46
+ // 5. Групповое чтение множества ключей
47
+ console.log("5. Групповое чтение ключей...");
48
+ const keysToRead = [1n, 2n, 3n, 42n, 5n]; // 42n не существует
49
+ const readResults = await readDbi.getBatch(keysToRead);
50
+ console.log("Результат чтения:");
51
+ readResults.forEach(r => {
52
+ console.log(` Ключ ${r.key}: ${r.found ? r.value : 'НЕ НАЙДЕН'}`);
53
+ });
54
+
55
+ await r.commit();
56
+
57
+ // 6. Создаем транзакцию для удаления
58
+ console.log("6. Создаем транзакцию для удаления...");
59
+ const d = await env.startWrite();
60
+ const delDbi = await d.openMap({ keyMode: keyMode.ordinal });
61
+
62
+ // 7. Групповое удаление ключей
63
+ console.log("7. Групповое удаление ключей...");
64
+ const keysToDelete = [2n, 4n, 42n]; // 42n не существует
65
+ const deleteResults = await delDbi.delBatch(keysToDelete);
66
+ console.log("Результат удаления:");
67
+ deleteResults.forEach(r => {
68
+ console.log(` Ключ ${r.key}: ${r.deleted ? 'УДАЛЕН' : 'НЕ НАЙДЕН'}`);
69
+ });
70
+
71
+ await d.commit();
72
+
73
+ // 8. Проверяем финальное состояние
74
+ console.log("8. Проверяем финальное состояние...");
75
+ const final = await env.startRead();
76
+ const finalDbi = await final.openMap({ keyMode: keyMode.ordinal });
77
+
78
+ const allKeys = [1n, 2n, 3n, 4n, 5n];
79
+ const finalResults = await finalDbi.getBatch(allKeys);
80
+ console.log("Финальное состояние:");
81
+ finalResults.forEach(r => {
82
+ console.log(` Ключ ${r.key}: ${r.found ? r.value : 'ОТСУТСТВУЕТ'}`);
83
+ });
84
+
85
+ await final.commit();
86
+
87
+ await env.close();
88
+ console.log("Тест завершен успешно!");
89
+
90
+ console.log("\n=== Тест с двумя базами данных ===");
91
+
92
+ // Открываем заново для multi-database теста
93
+ await env.open({ path: testPath });
94
+
95
+ // 1. Создаем транзакцию и две базы данных
96
+ console.log("1. Создаем транзакцию и две базы...");
97
+ const multiW = await env.startWrite();
98
+ const oddDbi = await multiW.openMap({
99
+ name: "odd_numbers",
100
+ keyMode: keyMode.ordinal,
101
+ create: true
102
+ });
103
+ const evenDbi = await multiW.openMap({
104
+ name: "even_numbers",
105
+ keyMode: keyMode.ordinal,
106
+ create: true
107
+ });
108
+
109
+ // 2. Заполняем начальными данными
110
+ console.log("2. Заполняем начальными данными...");
111
+ const oddInitial = [
112
+ { key: 1n, value: "один" },
113
+ { key: 3n, value: "три" },
114
+ { key: 5n, value: "пять" }
115
+ ];
116
+ const evenInitial = [
117
+ { key: 2n, value: "два" },
118
+ { key: 4n, value: "четыре" }
119
+ ];
120
+
121
+ const oddResults = await oddDbi.putBatch(oddInitial);
122
+ const evenResults = await evenDbi.putBatch(evenInitial);
123
+
124
+ console.log("Нечетные числа записаны:", oddResults.every(r => r.success));
125
+ console.log("Четные числа записаны:", evenResults.every(r => r.success));
126
+
127
+ // 3. Добавляем дополнительные данные в ту же транзакцию
128
+ console.log("3. Добавляем дополнительные числа...");
129
+ const oddAdditional = [
130
+ { key: 7n, value: "семь" },
131
+ { key: 9n, value: "девять" }
132
+ ];
133
+ const evenAdditional = [
134
+ { key: 6n, value: "шесть" },
135
+ { key: 8n, value: "восемь" }
136
+ ];
137
+
138
+ await oddDbi.putBatch(oddAdditional);
139
+ await evenDbi.putBatch(evenAdditional);
140
+
141
+ console.log("Дополнительные числа добавлены");
142
+
143
+ // 4. Коммитим всё одной транзакцией
144
+ console.log("4. Коммитим обе базы одной транзакцией...");
145
+ await multiW.commit();
146
+
147
+ // 5. Проверяем результаты в обеих базах
148
+ console.log("5. Проверяем результаты...");
149
+ const checkR = await env.startRead();
150
+ const checkOddDbi = await checkR.openMap({
151
+ name: "odd_numbers",
152
+ keyMode: keyMode.ordinal
153
+ });
154
+ const checkEvenDbi = await checkR.openMap({
155
+ name: "even_numbers",
156
+ keyMode: keyMode.ordinal
157
+ });
158
+
159
+ // Читаем все нечетные числа
160
+ const oddKeys = [1n, 3n, 5n, 7n, 9n];
161
+ const oddFinalResults = await checkOddDbi.getBatch(oddKeys);
162
+ console.log("База нечетных чисел:");
163
+ oddFinalResults.forEach(r => {
164
+ console.log(` ${r.key}: ${r.found ? r.value : 'ОТСУТСТВУЕТ'}`);
165
+ });
166
+
167
+ // Читаем все четные числа
168
+ const evenKeys = [2n, 4n, 6n, 8n];
169
+ const evenFinalResults = await checkEvenDbi.getBatch(evenKeys);
170
+ console.log("База четных чисел:");
171
+ evenFinalResults.forEach(r => {
172
+ console.log(` ${r.key}: ${r.found ? r.value : 'ОТСУТСТВУЕТ'}`);
173
+ });
174
+
175
+ await checkR.commit();
176
+
177
+ // 6. Тест межбазовых операций в одной транзакции
178
+ console.log("6. Тест межбазовых операций...");
179
+ const crossW = await env.startWrite();
180
+ const crossOddDbi = await crossW.openMap({
181
+ name: "odd_numbers",
182
+ keyMode: keyMode.ordinal
183
+ });
184
+ const crossEvenDbi = await crossW.openMap({
185
+ name: "even_numbers",
186
+ keyMode: keyMode.ordinal
187
+ });
188
+
189
+ // Удаляем некоторые числа из обеих баз
190
+ console.log("Удаляем 5 из нечетных и 4 из четных...");
191
+ await crossOddDbi.delBatch([5n]);
192
+ await crossEvenDbi.delBatch([4n]);
193
+
194
+ // Добавляем новые числа
195
+ console.log("Добавляем 11 в нечетные и 10 в четные...");
196
+ await crossOddDbi.putBatch([{ key: 11n, value: "одиннадцать" }]);
197
+ await crossEvenDbi.putBatch([{ key: 10n, value: "десять" }]);
198
+
199
+ await crossW.commit();
200
+
201
+ // 7. Финальная проверка
202
+ console.log("7. Финальная проверка всех баз...");
203
+ const finalCheckR = await env.startRead();
204
+ const finalOddDbi = await finalCheckR.openMap({
205
+ name: "odd_numbers",
206
+ keyMode: keyMode.ordinal
207
+ });
208
+ const finalEvenDbi = await finalCheckR.openMap({
209
+ name: "even_numbers",
210
+ keyMode: keyMode.ordinal
211
+ });
212
+
213
+ const allOddKeys = [1n, 3n, 5n, 7n, 9n, 11n];
214
+ const allEvenKeys = [2n, 4n, 6n, 8n, 10n];
215
+
216
+ const finalOddResults = await finalOddDbi.getBatch(allOddKeys);
217
+ const finalEvenResults = await finalEvenDbi.getBatch(allEvenKeys);
218
+
219
+ console.log("Финальное состояние нечетных:");
220
+ finalOddResults.forEach(r => {
221
+ console.log(` ${r.key}: ${r.found ? r.value : 'УДАЛЕНО'}`);
222
+ });
223
+
224
+ console.log("Финальное состояние четных:");
225
+ finalEvenResults.forEach(r => {
226
+ console.log(` ${r.key}: ${r.found ? r.value : 'УДАЛЕНО'}`);
227
+ });
228
+
229
+ await finalCheckR.commit();
230
+
231
+ await env.close();
232
+ console.log("Тест с двумя базами завершен успешно!");
233
+
234
+ } catch (error) {
235
+ console.error("Ошибка теста:", error);
236
+ } finally {
237
+ try {
238
+ await env.terminate();
239
+ } catch (e) {
240
+ console.error("Ошибка при завершении:", e.message);
241
+ }
242
+ }
243
+ })();
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+ const MDBX = require('../lib/nativemou.js');
5
+ const { MDBX_Env, MDBX_Param } = MDBX;
6
+
7
+ const testCursorMode = async () => {
8
+ const path = 'test-cursor-mode';
9
+
10
+ await Promise.all([
11
+ fs.promises.rm(path, { recursive: true, force: true })
12
+ ]);
13
+
14
+ const { keyMode, cursorMode } = MDBX_Param;
15
+
16
+ const db = new MDBX_Env();
17
+
18
+ console.log('Opening database...');
19
+ await db.open({
20
+ path: path,
21
+ valueFlag: MDBX_Param.valueFlag.string
22
+ });
23
+
24
+ // добавим тестовые данные
25
+ const w = db.startWrite();
26
+ const wdbi = w.createMap(keyMode.ordinal);
27
+ for (let i = 1; i <= 10; i++) {
28
+ wdbi.put(i, `value${i}`);
29
+ }
30
+ w.commit();
31
+
32
+ // читаем данные
33
+ const r = db.startRead();
34
+ const dbi = r.openMap(keyMode.ordinal);
35
+
36
+ console.log('=== Testing forEach variants ===');
37
+
38
+ // 1. forEach(fn)
39
+ console.log('\n1. forEach(fn):');
40
+ let count = dbi.forEach((k, v, i) => {
41
+ console.log(` ${i}: ${k} = ${v}`);
42
+ return i >= 2; // останавливаем после 3 элементов
43
+ });
44
+ console.log(`Processed ${count} items`);
45
+
46
+ // 2. forEach(fromKey, fn)
47
+ console.log('\n2. forEach(fromKey=5, fn):');
48
+ count = dbi.forEach(5, (k, v, i) => {
49
+ console.log(` ${i}: ${k} = ${v}`);
50
+ return i >= 2; // останавливаем после 3 элементов
51
+ });
52
+ console.log(`Processed ${count} items`);
53
+
54
+ // 3. forEach(fromKey, cursorMode, fn) - строковый режим
55
+ console.log('\n3. forEach(fromKey=7, "keyGreater", fn):');
56
+ count = dbi.forEach(7, 'keyGreater', (k, v, i) => {
57
+ console.log(` ${i}: ${k} = ${v}`);
58
+ return i >= 1; // останавливаем после 2 элементов
59
+ });
60
+ console.log(`Processed ${count} items`);
61
+
62
+ // 4. forEach(fromKey, cursorMode, fn) - числовой режим key_lesser_or_equal (обратное сканирование)
63
+ console.log('\n4. forEach(fromKey=7, cursorMode.key_lesser_or_equal, fn):');
64
+ count = dbi.forEach(7, cursorMode.key_lesser_or_equal, (k, v, i) => {
65
+ console.log(` ${i}: ${k} = ${v}`);
66
+ return i >= 2; // останавливаем после 3 элементов
67
+ });
68
+ console.log(`Processed ${count} items`);
69
+
70
+ // 5. forEach(fromKey, cursorMode, fn) - keyEqual
71
+ console.log('\n5. forEach(fromKey=5, "keyEqual", fn):');
72
+ count = dbi.forEach(5, 'keyEqual', (k, v, i) => {
73
+ console.log(` ${i}: ${k} = ${v}`);
74
+ return i >= 0; // останавливаем после первого элемента для демонстрации
75
+ });
76
+ console.log(`Processed ${count} items`);
77
+
78
+ r.commit();
79
+ await db.close();
80
+
81
+ console.log('\n=== Test completed successfully ===');
82
+ }
83
+
84
+ testCursorMode().catch(console.error);
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+ const MDBX = require('../lib/nativemou.js');
5
+ const { MDBX_Env, MDBX_Param } = MDBX;
6
+
7
+ const testMultiMode = async () => {
8
+ const path = 'test-multi-mode';
9
+
10
+ await Promise.all([
11
+ fs.promises.rm(path, { recursive: true, force: true })
12
+ ]);
13
+
14
+ const { keyMode, valueMode, cursorMode } = MDBX_Param;
15
+
16
+ const db = new MDBX_Env();
17
+
18
+ console.log('Opening database with multi value mode...');
19
+ await db.open({
20
+ path: path,
21
+ valueFlag: MDBX_Param.valueFlag.string
22
+ });
23
+
24
+ // добавим тестовые данные в multi режиме
25
+ const w = db.startWrite();
26
+ const wdbi = w.createMap(keyMode.ordinal, valueMode.multi);
27
+
28
+ // Добавляем несколько значений для одного ключа
29
+ wdbi.put(5, 'value5_1');
30
+ wdbi.put(5, 'value5_2');
31
+ wdbi.put(5, 'value5_3');
32
+
33
+ // Добавляем данные для других ключей
34
+ for (let i = 1; i <= 10; i++) {
35
+ if (i !== 5) {
36
+ wdbi.put(i, `value${i}`);
37
+ }
38
+ }
39
+
40
+ w.commit();
41
+
42
+ // читаем данные
43
+ const r = db.startRead();
44
+ const dbi = r.openMap(keyMode.ordinal, valueMode.multi);
45
+
46
+ console.log('=== Testing multi mode with key_equal ===');
47
+
48
+ // 1. Обычный forEach - должен показать все записи
49
+ console.log('\n1. forEach(fn) - все записи:');
50
+ let count = dbi.forEach((k, v, i) => {
51
+ console.log(` ${i}: key=${k} value=${v}`);
52
+ return false; // продолжаем
53
+ });
54
+ console.log(`Total processed: ${count} items`);
55
+
56
+ // 2. forEach с key_equal для ключа 5 - должен показать все три записи
57
+ console.log('\n2. forEach(key=5, "keyEqual", fn) - три записи для ключа 5:');
58
+ count = dbi.forEach(5, 'keyEqual', (k, v, i) => {
59
+ console.log(` ${i}: key=${k} value=${v}`);
60
+ });
61
+ console.log(`Processed: ${count} items`);
62
+
63
+ // 3. forEach с key_greater_or_equal для ключа 5 - должен показать все записи начиная с ключа 5
64
+ console.log('\n3. forEach(key=5, "keyGreaterOrEqual", fn) - все записи от ключа 5:');
65
+ count = dbi.forEach(5, 'keyGreaterOrEqual', (k, v, i) => {
66
+ console.log(` ${i}: key=${k} value=${v}`);
67
+ return i >= 4; // останавливаем после 5 элементов
68
+ });
69
+ console.log(`Processed: ${count} items`);
70
+
71
+ // 4. keysFrom с key_equal - должен вернуть три ключа
72
+ console.log('\n4. keysFrom(key=5, limit=10, "keyEqual") - три ключа:');
73
+ const keysEqual = dbi.keysFrom(5, 10, 'keyEqual');
74
+ console.log(`Keys: [${keysEqual.join(', ')}]`);
75
+
76
+ // 5. keysFrom с key_greater_or_equal - должен вернуть все ключи от 5
77
+ console.log('\n5. keysFrom(key=5, limit=10, "keyGreaterOrEqual") - все ключи от 5:');
78
+ const keysGreater = dbi.keysFrom(5, 10, 'keyGreaterOrEqual');
79
+ console.log(`Keys: [${keysGreater.join(', ')}]`);
80
+
81
+ r.commit();
82
+ await db.close();
83
+
84
+ console.log('\n=== Multi mode test completed successfully ===');
85
+ }
86
+
87
+ testMultiMode().catch(console.error);