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
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ const { parentPort } = require("worker_threads");
3
+ const MDBX = require("./nativemou.js");
4
+ const { MDBX_Env } = MDBX;
5
+
6
+ // Хранилища
7
+ let env = null;
8
+ const txns = new Map(); // txnId -> { txn, write }
9
+ const dbis = new Map(); // dbiId -> { txnId, dbi }
10
+
11
+ function ok(id, result) { parentPort.postMessage({ id, ok: true, result }); }
12
+ function fail(id, error) { parentPort.postMessage({ id, ok: false, error }); }
13
+
14
+ async function handler(msg) {
15
+ const { id, cmd, params } = msg;
16
+ try {
17
+ switch (cmd) {
18
+ case "env_open":
19
+ if (env) throw new Error("already open");
20
+ env = new MDBX_Env();
21
+ await env.openSync(params || {});
22
+ return ok(id, true);
23
+
24
+ case "env_close":
25
+ if (env) {
26
+ env.closeSync();
27
+ env = null;
28
+ txns.clear();
29
+ dbis.clear();
30
+ }
31
+ return ok(id, true);
32
+
33
+ case "txn_begin": {
34
+ if (!env) throw new Error("env not open");
35
+ const { txnId, mode } = params;
36
+ if (txns.has(txnId)) throw new Error("txn exists");
37
+ const txn = (mode === "write") ? env.startWrite() : env.startRead();
38
+ txns.set(txnId, { txn, write: mode === "write" });
39
+ return ok(id, true);
40
+ }
41
+
42
+ case "txn_commit": {
43
+ const { txnId } = params;
44
+ const t = txns.get(txnId);
45
+ if (!t) throw new Error("no txn");
46
+ t.txn.commit();
47
+ txns.delete(txnId);
48
+ // удалить связанные dbi
49
+ for (const [k, v] of dbis) if (v.txnId === txnId) dbis.delete(k);
50
+ return ok(id, true);
51
+ }
52
+
53
+ case "txn_abort": {
54
+ const { txnId } = params;
55
+ const t = txns.get(txnId);
56
+ if (!t) return ok(id, true);
57
+ if (t.txn.abort) t.txn.abort();
58
+ txns.delete(txnId);
59
+ for (const [k, v] of dbis) if (v.txnId === txnId) dbis.delete(k);
60
+ return ok(id, true);
61
+ }
62
+
63
+ case "map_open": {
64
+ const { txnId, dbiId, name, keyMode, valMode, flags, create } = params;
65
+ const t = txns.get(txnId);
66
+ if (!t) throw new Error("no txn");
67
+ let dbi;
68
+ if (create) {
69
+ // createMap принимает (keyMode, valueMode)
70
+ if (valMode !== undefined && valMode !== 0) {
71
+ dbi = t.txn.createMap(keyMode, valMode);
72
+ } else {
73
+ dbi = t.txn.createMap(keyMode);
74
+ }
75
+ } else {
76
+ // openMap для чтения принимает только keyMode
77
+ dbi = t.txn.openMap(keyMode);
78
+ }
79
+ dbis.set(dbiId, { txnId, dbi });
80
+ return ok(id, { meta: { name: name || "", keyMode, valMode } });
81
+ }
82
+
83
+ case "dbi_put": {
84
+ const { txnId, dbiId, key, value, flags = 0 } = params;
85
+ const d = dbis.get(dbiId);
86
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
87
+ d.dbi.put(key, value, flags);
88
+ return ok(id, true);
89
+ }
90
+
91
+ case "dbi_get": {
92
+ const { txnId, dbiId, key } = params;
93
+ const d = dbis.get(dbiId);
94
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
95
+ const val = d.dbi.get(key);
96
+ // Если val это Buffer, преобразуем в строку для удобства
97
+ const result = (val && Buffer.isBuffer(val)) ? val.toString() : val;
98
+ return ok(id, result);
99
+ }
100
+
101
+ case "dbi_del": {
102
+ const { txnId, dbiId, key } = params;
103
+ const d = dbis.get(dbiId);
104
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
105
+ const r = d.dbi.del(key);
106
+ return ok(id, r);
107
+ }
108
+
109
+ case "dbi_stat": {
110
+ const { txnId, dbiId } = params;
111
+ const d = dbis.get(dbiId);
112
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
113
+ return ok(id, d.dbi.stat());
114
+ }
115
+
116
+ case "dbi_iter_all": {
117
+ const { txnId, dbiId } = params;
118
+ const d = dbis.get(dbiId);
119
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
120
+ const out = [];
121
+ d.dbi.forEach((k, v) => {
122
+ out.push({ key: k, value: v });
123
+ return true;
124
+ });
125
+ return ok(id, out);
126
+ }
127
+
128
+ case "dbi_get_batch": {
129
+ // Групповое чтение множества ключей
130
+ const { txnId, dbiId, keys } = params;
131
+ const d = dbis.get(dbiId);
132
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
133
+
134
+ const results = [];
135
+ for (const key of keys) {
136
+ try {
137
+ const val = d.dbi.get(key);
138
+ if (val !== undefined && val !== null) {
139
+ const result = (val && Buffer.isBuffer(val)) ? val.toString() : val;
140
+ results.push({ key, value: result, found: true });
141
+ } else {
142
+ results.push({ key, value: null, found: false });
143
+ }
144
+ } catch (e) {
145
+ results.push({ key, value: null, found: false });
146
+ }
147
+ }
148
+ return ok(id, results);
149
+ }
150
+
151
+ case "dbi_put_batch": {
152
+ // Групповая запись множества пар ключ-значение
153
+ const { txnId, dbiId, items, flags = 0 } = params;
154
+ const d = dbis.get(dbiId);
155
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
156
+
157
+ const results = [];
158
+ for (const item of items) {
159
+ try {
160
+ d.dbi.put(item.key, item.value, flags);
161
+ results.push({ key: item.key, success: true });
162
+ } catch (e) {
163
+ results.push({ key: item.key, success: false, error: e.message });
164
+ }
165
+ }
166
+ return ok(id, results);
167
+ }
168
+
169
+ case "dbi_del_batch": {
170
+ // Групповое удаление множества ключей
171
+ const { txnId, dbiId, keys } = params;
172
+ const d = dbis.get(dbiId);
173
+ if (!d || d.txnId !== txnId) throw new Error("no dbi");
174
+
175
+ const results = [];
176
+ for (const key of keys) {
177
+ try {
178
+ const r = d.dbi.del(key);
179
+ results.push({ key, deleted: r });
180
+ } catch (e) {
181
+ results.push({ key, deleted: false, error: e.message });
182
+ }
183
+ }
184
+ return ok(id, results);
185
+ }
186
+
187
+ default:
188
+ throw new Error("unknown cmd " + cmd);
189
+ }
190
+ } catch (e) {
191
+ return fail(id, e.message || String(e));
192
+ }
193
+ }
194
+
195
+ parentPort.on("message", handler);
@@ -0,0 +1,6 @@
1
+ const os = require('os');
2
+
3
+ const nativePath = '../build/Release/mdbxmou';
4
+ const nativeModule = require(nativePath);
5
+ // Экспортируем объединенный модуль
6
+ module.exports = nativeModule;
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "main": "lib/nativemou.js",
3
+ "dependencies": {
4
+ "cmake-js": "^7.3.1",
5
+ "node-addon-api": "^8.5.0"
6
+ },
7
+ "scripts": {
8
+ "e3": "node ./test/e3.js",
9
+ "e4": "node ./test/e4.js",
10
+ "e5": "node ./test/e5.js",
11
+ "test": "node ./test/e3.js && node ./test/e4.js && node ./test/e5.js",
12
+ "build": "node build.js",
13
+ "install": "node build.js"
14
+ },
15
+ "gypfile": true,
16
+ "name": "mdbxmou",
17
+ "version": "0.1.26",
18
+ "description": "Node bindings for mdbx",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ikonopistsev/mdbxmou.git"
22
+ },
23
+ "keywords": [
24
+ "mdbx",
25
+ "libmdbx",
26
+ "database",
27
+ "db",
28
+ "kv",
29
+ "bindings",
30
+ "embedded"
31
+ ],
32
+ "author": "Igor Ikonopistsev",
33
+ "license": "Apache-2.0",
34
+ "bugs": {
35
+ "url": "https://github.com/ikonopistsev/mdbxmou/issues"
36
+ },
37
+ "homepage": "https://github.com/ikonopistsev/mdbxmou#readme"
38
+ }
@@ -0,0 +1,34 @@
1
+ #include "envmou_close.hpp"
2
+ #include "envmou.hpp"
3
+
4
+ namespace mdbxmou {
5
+
6
+ void async_close::Execute()
7
+ {
8
+ // выдадим идентфикатор потока для лога (thread_id)
9
+ // fprintf(stderr, "TRACE: async_close id=%d\n", gettid());
10
+
11
+ try {
12
+ that_.do_close();
13
+ } catch (const std::exception& e) {
14
+ SetError(e.what());
15
+ }
16
+ }
17
+
18
+ void async_close::OnOK()
19
+ {
20
+ auto env = Env();
21
+
22
+ that_.unlock();
23
+
24
+ deferred_.Resolve(env.Undefined());
25
+ }
26
+
27
+ void async_close::OnError(const Napi::Error& e)
28
+ {
29
+ that_.unlock();
30
+
31
+ deferred_.Reject(e.Value());
32
+ }
33
+
34
+ } // namespace mdbxmou
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ #include <napi.h>
4
+ #include <mdbx.h++>
5
+
6
+ namespace mdbxmou {
7
+
8
+ class envmou;
9
+
10
+ class async_close final
11
+ : public Napi::AsyncWorker
12
+ {
13
+ Napi::Promise::Deferred deferred_;
14
+ envmou& that_;
15
+
16
+ public:
17
+ async_close(Napi::Env env, envmou& t)
18
+ : Napi::AsyncWorker(env)
19
+ , deferred_(Napi::Promise::Deferred::New(env))
20
+ , that_(t)
21
+ { }
22
+
23
+ void Execute() override;
24
+ void OnOK() override;
25
+ void OnError(const Napi::Error& e) override;
26
+
27
+ Napi::Promise GetPromise() const {
28
+ return deferred_.Promise();
29
+ }
30
+ };
31
+
32
+ } // namespace mdbxmou
@@ -0,0 +1,29 @@
1
+ #include "envmou_copy_to.hpp"
2
+ #include "envmou.hpp"
3
+
4
+ namespace mdbxmou {
5
+
6
+ void async_copy::Execute()
7
+ {
8
+ // выдадим идентфикатор потока для лога (thread_id)
9
+ // fprintf(stderr, "TRACE: async_copy id=%d\n", gettid());
10
+
11
+ auto rc = mdbx_env_copy(that_, dest_.c_str(), flags_);
12
+ if (rc != MDBX_SUCCESS) {
13
+ SetError(mdbx_strerror(rc));
14
+ }
15
+ }
16
+
17
+ void async_copy::OnOK()
18
+ {
19
+ that_.unlock();
20
+ deferred_.Resolve(Env().Undefined());
21
+ }
22
+
23
+ void async_copy::OnError(const Napi::Error& e)
24
+ {
25
+ that_.unlock();
26
+ deferred_.Reject(e.Value());
27
+ }
28
+
29
+ } // namespace mdbxmou
@@ -0,0 +1,38 @@
1
+ #pragma once
2
+ #include <napi.h>
3
+ #include <mdbx.h++>
4
+
5
+ namespace mdbxmou {
6
+
7
+ class envmou;
8
+
9
+ class async_copy
10
+ : public Napi::AsyncWorker
11
+ {
12
+ Napi::Promise::Deferred deferred_;
13
+ envmou& that_;
14
+ std::string dest_{};
15
+ MDBX_copy_flags_t flags_{MDBX_CP_DEFAULTS};
16
+
17
+ public:
18
+ async_copy(Napi::Env env, envmou& t,
19
+ std::string dest, MDBX_copy_flags_t flags)
20
+ : Napi::AsyncWorker(env)
21
+ , deferred_(Napi::Promise::Deferred::New(env))
22
+ , that_(t)
23
+ , dest_(std::move(dest))
24
+ , flags_(flags)
25
+ { }
26
+
27
+ void Execute() override;
28
+
29
+ void OnOK() override;
30
+
31
+ void OnError(const Napi::Error& e) override;
32
+
33
+ Napi::Promise GetPromise() const {
34
+ return deferred_.Promise();
35
+ }
36
+ };
37
+
38
+ } // namespace mdbxmou
@@ -0,0 +1,201 @@
1
+ #include "envmou_keys.hpp"
2
+ #include "envmou.hpp"
3
+ #include "dbimou.hpp"
4
+
5
+ namespace mdbxmou {
6
+
7
+ void async_keys::Execute()
8
+ {
9
+ try {
10
+ // стартуем транзакцию
11
+ auto txn = start_transaction();
12
+ for (auto& req : query_)
13
+ {
14
+ mdbx::map_handle dbi{};
15
+ auto db_mode = req.db_mod;
16
+ if (db_mode.val & db_mode::accede) {
17
+ dbi = txn.open_map_accede(req.db);
18
+ } else {
19
+ dbi = txn.open_map(req.db, req.key_mod, req.val_mod);
20
+ }
21
+ do_keys(txn, dbi, req);
22
+ }
23
+
24
+ txn.commit();
25
+ } catch (const std::exception& e) {
26
+ SetError(e.what());
27
+ } catch (...) {
28
+ SetError("async_keys::Execute");
29
+ }
30
+ }
31
+
32
+ static Napi::Value write_row(Napi::Env env, const keys_line& row)
33
+ {
34
+ auto& param = row.item;
35
+ auto key_mode = row.key_mod;
36
+ auto key_flag = row.key_flag;
37
+ auto js_arr = Napi::Array::New(env, param.size());
38
+ for (std::size_t j = 0; j < param.size(); ++j) {
39
+ const auto& item = param[j];
40
+ if (key_mode.val & key_mode::ordinal) {
41
+ js_arr.Set(j, (key_flag.val & base_flag::number) ?
42
+ Napi::Number::New(env, item.id_buf) : Napi::BigInt::New(env, item.id_buf));
43
+ } else {
44
+ js_arr.Set(j, (key_flag.val & base_flag::string) ?
45
+ Napi::String::New(env, item.key_buf.data(), item.key_buf.size()) :
46
+ Napi::Buffer<char>::Copy(env, item.key_buf.data(), item.key_buf.size()));
47
+ }
48
+ }
49
+ return js_arr;
50
+ }
51
+
52
+ void async_keys::OnOK()
53
+ {
54
+ auto env = Env();
55
+
56
+ --env_;
57
+
58
+ if (single_ && (query_.size() == 1)) {
59
+ const auto& row = query_[0];
60
+ deferred_.Resolve(write_row(env, row));
61
+ return;
62
+ }
63
+
64
+ Napi::Array result = Napi::Array::New(env, query_.size());
65
+ for (std::size_t i = 0; i < query_.size(); ++i) {
66
+ Napi::Object js_row = Napi::Object::New(env);
67
+ const auto& row = query_[i];
68
+ if (!row.db.empty()) {
69
+ js_row.Set("db", Napi::String::New(env, row.db_name));
70
+ }
71
+ result.Set(i, write_row(env, row));
72
+ }
73
+
74
+ deferred_.Resolve(result);
75
+ }
76
+
77
+ void async_keys::OnError(const Napi::Error& e)
78
+ {
79
+ --env_;
80
+
81
+ deferred_.Reject(e.Value());
82
+ }
83
+
84
+ txnmou_managed async_keys::start_transaction()
85
+ {
86
+ MDBX_txn *ptr;
87
+ mdbx::error::success_or_throw(::mdbx_txn_begin(env_, nullptr, txn_mode_, &ptr));
88
+ return { ptr };
89
+ }
90
+
91
+ void async_keys::do_keys(txnmou_managed& txn,
92
+ mdbx::map_handle dbi, keys_line& arg0)
93
+ {
94
+ auto& item = arg0.item;
95
+ if (!arg0.has_from_key) {
96
+ // Обычный режим - получаем все ключи
97
+ auto stat = dbimou::get_stat(txn, dbi);
98
+ item.reserve(stat.ms_entries);
99
+
100
+ auto cursor = txn.open_cursor(dbi);
101
+ if (mdbx::is_ordinal(arg0.key_mod)) {
102
+ cursor.scan([&](const mdbx::pair& f) {
103
+ async_key rc{};
104
+ rc.id_buf = f.key.as_uint64();
105
+ item.push_back(std::move(rc));
106
+ return false;
107
+ });
108
+ } else {
109
+ cursor.scan([&](const mdbx::pair& f) {
110
+ async_key rc{};
111
+ rc.key_buf.assign(f.key.char_ptr(), f.key.end_char_ptr());
112
+ item.push_back(std::move(rc));
113
+ return false;
114
+ });
115
+ }
116
+ } else {
117
+ do_keys_from(txn, dbi, arg0);
118
+ }
119
+ }
120
+
121
+ void async_keys::do_keys_from(txnmou_managed& txn,
122
+ mdbx::map_handle dbi, keys_line& arg0)
123
+ {
124
+ // сыллка на массив результатов
125
+ auto& item = arg0.item;
126
+ std::size_t count = 0;
127
+ using move_operation = mdbx::cursor::move_operation;
128
+
129
+ auto cursor = txn.open_cursor(dbi);
130
+
131
+ keymou from_key = mdbx::is_ordinal(arg0.key_mod) ?
132
+ keymou{arg0.id_buf} :
133
+ keymou{mdbx::slice{arg0.key_buf.data(), arg0.key_buf.size()}};
134
+
135
+ // Определяем направление сканирования
136
+ auto turn_mode = move_operation::next;
137
+ auto cursor_mode = arg0.cursor_mode;
138
+ switch (cursor_mode) {
139
+ case move_operation::key_lesser_than:
140
+ case move_operation::key_lesser_or_equal:
141
+ case move_operation::multi_exactkey_value_lesser_than:
142
+ case move_operation::multi_exactkey_value_lesser_or_equal:
143
+ turn_mode = move_operation::previous;
144
+ break;
145
+ case move_operation::key_equal:
146
+ case move_operation::multi_exactkey_value_equal:
147
+ turn_mode = move_operation::next;
148
+ break;
149
+ default:
150
+ turn_mode = move_operation::next;
151
+ break;
152
+ }
153
+
154
+ bool is_key_equal_mode = (cursor_mode == move_operation::key_equal ||
155
+ cursor_mode == move_operation::multi_exactkey_value_equal);
156
+
157
+ std::size_t index{};
158
+ if (mdbx::is_ordinal(arg0.key_mod)) {
159
+ // Создаем ключ для позиционирования
160
+ cursor.scan_from([&](const mdbx::pair& f) {
161
+ if (index >= arg0.limit) {
162
+ return true; // останавливаем сканирование
163
+ }
164
+
165
+ keymou key{f.key};
166
+ if (is_key_equal_mode) {
167
+ if (arg0.id_buf != key.as_int64()) {
168
+ return true; // останавливаем сканирование
169
+ }
170
+ }
171
+
172
+ async_key rc{};
173
+ rc.id_buf = key.as_uint64();
174
+ item.push_back(std::move(rc));
175
+ index++;
176
+ return false; // продолжаем сканирование
177
+ }, from_key, arg0.cursor_mode, turn_mode);
178
+ } else {
179
+ // Создаем ключ для позиционирования
180
+ cursor.scan_from([&](const mdbx::pair& f) {
181
+ if (index >= arg0.limit) {
182
+ return true; // останавливаем сканирование
183
+ }
184
+
185
+ keymou key{f.key};
186
+ if (is_key_equal_mode) {
187
+ if (from_key != key) {
188
+ return true; // останавливаем сканирование
189
+ }
190
+ }
191
+
192
+ async_key rc{};
193
+ rc.id_buf = key.as_uint64();
194
+ item.push_back(std::move(rc));
195
+ index++;
196
+ return false; // продолжаем сканирование
197
+ }, from_key, arg0.cursor_mode, turn_mode);
198
+ }
199
+ }
200
+
201
+ } // namespace mdbxmou
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include "querymou.hpp"
4
+
5
+ namespace mdbxmou {
6
+
7
+ class envmou;
8
+
9
+ class async_keys
10
+ : public Napi::AsyncWorker
11
+ {
12
+ Napi::Promise::Deferred deferred_;
13
+ envmou& env_;
14
+ txn_mode txn_mode_{};
15
+ // действия для выполнения
16
+ keys_request query_{};
17
+ // упрощенный режим 1 массив
18
+ bool single_{false};
19
+
20
+ public:
21
+ async_keys(Napi::Env env, envmou& e,
22
+ txn_mode txn_mode, keys_request query, bool single = false)
23
+ : Napi::AsyncWorker{env}
24
+ , deferred_{Napi::Promise::Deferred::New(env)}
25
+ , env_{e}
26
+ , txn_mode_{txn_mode}
27
+ , query_{std::move(query)}
28
+ , single_{single}
29
+ { }
30
+
31
+ void Execute() override;
32
+
33
+ void OnOK() override;
34
+
35
+ void OnError(const Napi::Error& e) override;
36
+
37
+ Napi::Promise GetPromise() const {
38
+ return deferred_.Promise();
39
+ }
40
+
41
+ txnmou_managed start_transaction();
42
+
43
+ void do_keys(txnmou_managed& txn,
44
+ mdbx::map_handle dbi, keys_line& arg0);
45
+
46
+ void do_keys_from(txnmou_managed& txn,
47
+ mdbx::map_handle dbi, keys_line& arg0);
48
+ };
49
+
50
+ } // namespace mdbxmou
@@ -0,0 +1,38 @@
1
+ #include "envmou_open.hpp"
2
+ #include "envmou.hpp"
3
+
4
+ namespace mdbxmou {
5
+
6
+ void async_open::Execute()
7
+ {
8
+ // выдадим идентфикатор потока для лога (thread_id)
9
+ // fprintf(stderr, "TRACE: async_open id=%d\n", gettid());
10
+
11
+ try {
12
+ auto e = envmou::create_and_open(arg0_);
13
+ that_.attach(e, arg0_);
14
+ } catch (const std::exception& e) {
15
+ SetError(e.what());
16
+ }
17
+ }
18
+
19
+ void async_open::OnOK()
20
+ {
21
+ // выдадим идентфикатор потока для лога (thread_id)
22
+ // fprintf(stderr, "TRACE: async_open OnOK id=%d\n", gettid());
23
+
24
+ auto env = Env();
25
+
26
+ that_.unlock();
27
+
28
+ deferred_.Resolve(env.Undefined());
29
+ }
30
+
31
+ void async_open::OnError(const Napi::Error& e)
32
+ {
33
+ that_.unlock();
34
+
35
+ deferred_.Reject(e.Value());
36
+ }
37
+
38
+ } // namespace mdbxmou
@@ -0,0 +1,33 @@
1
+ #pragma once
2
+
3
+ #include "env_arg0.hpp"
4
+
5
+ namespace mdbxmou {
6
+
7
+ class envmou;
8
+
9
+ class async_open final
10
+ : public Napi::AsyncWorker
11
+ {
12
+ Napi::Promise::Deferred deferred_;
13
+ envmou& that_;
14
+ env_arg0 arg0_{};
15
+
16
+ public:
17
+ async_open(Napi::Env env, envmou& t, const env_arg0& a)
18
+ : Napi::AsyncWorker(env)
19
+ , deferred_(Napi::Promise::Deferred::New(env))
20
+ , that_(t)
21
+ , arg0_(a)
22
+ { }
23
+
24
+ void Execute() override;
25
+ void OnOK() override;
26
+ void OnError(const Napi::Error& e) override;
27
+
28
+ Napi::Promise GetPromise() const {
29
+ return deferred_.Promise();
30
+ }
31
+ };
32
+
33
+ } // namespace mdbxmou