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,239 @@
1
+ #pragma once
2
+
3
+ #include <napi.h>
4
+ #include <mdbx.h++>
5
+ #include <cstdint>
6
+ #include <vector>
7
+
8
+ namespace mdbxmou {
9
+
10
+ using buffer_type = std::vector<char>;
11
+
12
+ struct txnmou_managed final
13
+ : public mdbx::txn_managed
14
+ {
15
+ txnmou_managed(MDBX_txn* txn)
16
+ {
17
+ txn::handle_ = txn;
18
+ }
19
+ };
20
+
21
+ struct cursormou_managed final
22
+ : public mdbx::cursor_managed
23
+ {
24
+ cursormou_managed(MDBX_cursor* cursor) noexcept
25
+ {
26
+ cursor::handle_ = cursor;
27
+ }
28
+ };
29
+
30
+ struct env_flag {
31
+ enum type : int {
32
+ validation = MDBX_VALIDATION,
33
+ rdonly = MDBX_RDONLY,
34
+ exclusive = MDBX_EXCLUSIVE,
35
+ accede = MDBX_ACCEDE,
36
+ writemap = MDBX_WRITEMAP,
37
+ nostickythreads = MDBX_NOSTICKYTHREADS,
38
+ nordahead = MDBX_NORDAHEAD,
39
+ nomeminit = MDBX_NOMEMINIT,
40
+ liforeclaim = MDBX_LIFORECLAIM,
41
+ nometasync = MDBX_NOMETASYNC,
42
+ safe_nosync = MDBX_SAFE_NOSYNC,
43
+ utterly_nosync = MDBX_UTTERLY_NOSYNC,
44
+ mask = MDBX_VALIDATION | MDBX_RDONLY | MDBX_EXCLUSIVE | MDBX_ACCEDE |
45
+ MDBX_WRITEMAP | MDBX_NOSTICKYTHREADS | MDBX_NORDAHEAD |
46
+ MDBX_NOMEMINIT | MDBX_LIFORECLAIM | MDBX_NOMETASYNC |
47
+ MDBX_SAFE_NOSYNC | MDBX_UTTERLY_NOSYNC
48
+ };
49
+ int val{};
50
+
51
+ static inline env_flag parse(const Napi::Value& arg0) {
52
+ return {arg0.As<Napi::Number>().Int32Value() & mask};
53
+ }
54
+
55
+ operator MDBX_env_flags() const noexcept {
56
+ return static_cast<MDBX_env_flags>(val & mask);
57
+ }
58
+ };
59
+
60
+ struct txn_mode {
61
+ enum type : int {
62
+ ro = MDBX_TXN_RDONLY
63
+ };
64
+ int val{};
65
+
66
+ static inline txn_mode parse(const Napi::Value& arg0) {
67
+ return {arg0.As<Napi::Number>().Int32Value() & ro};
68
+ }
69
+
70
+ operator MDBX_txn_flags() const noexcept {
71
+ return static_cast<MDBX_txn_flags>(val & ro);
72
+ }
73
+ };
74
+
75
+ struct query_mode
76
+ {
77
+ enum type : int {
78
+ get = 0x10000000,
79
+ del = 0x20000000,
80
+ upsert = MDBX_UPSERT,
81
+ update = MDBX_CURRENT,
82
+ insert_unique = MDBX_NOOVERWRITE,
83
+ write_mask = upsert | update | insert_unique,
84
+ mask = get | del | upsert | update | insert_unique
85
+ };
86
+ int val{get};
87
+
88
+ static inline query_mode parse(const txn_mode& mode, const Napi::Value& arg0) {
89
+ query_mode rc{arg0.As<Napi::Number>().Int32Value() & mask};
90
+ if ((mode.val & txn_mode::ro) && (rc.val & (del|upsert|update|insert_unique))) {
91
+ throw std::runtime_error("rw query in read-only transaction");
92
+ }
93
+ return rc;
94
+ }
95
+
96
+ operator mdbx::put_mode() const noexcept {
97
+ return static_cast<mdbx::put_mode>(val & write_mask);
98
+ }
99
+ };
100
+
101
+ struct key_mode
102
+ {
103
+ enum type : int {
104
+ reverse = MDBX_REVERSEKEY,
105
+ ordinal = MDBX_INTEGERKEY,
106
+ mask = MDBX_REVERSEKEY | MDBX_INTEGERKEY
107
+ };
108
+ int val{};
109
+
110
+ static inline key_mode parse(const Napi::Value& arg0) {
111
+ return {arg0.As<Napi::Number>().Int32Value() & mask};
112
+ }
113
+
114
+ operator mdbx::key_mode() const noexcept {
115
+ return static_cast<mdbx::key_mode>(val & mask);
116
+ }
117
+ };
118
+
119
+ struct value_mode
120
+ {
121
+ enum type : int {
122
+ multi = MDBX_DUPSORT,
123
+ multi_reverse = MDBX_DUPSORT | MDBX_REVERSEDUP,
124
+ multi_samelength = MDBX_DUPSORT | MDBX_DUPFIXED,
125
+ multi_ordinal = MDBX_DUPSORT | MDBX_DUPFIXED | MDBX_INTEGERDUP,
126
+ multi_reverse_samelength = MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED,
127
+ mask = MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP
128
+ };
129
+ int val{};
130
+
131
+ static inline value_mode parse(const Napi::Value& arg0) {
132
+ return {arg0.As<Napi::Number>().Int32Value() & mask};
133
+ }
134
+
135
+ operator mdbx::value_mode() const noexcept {
136
+ return static_cast<mdbx::value_mode>(val & mask);
137
+ }
138
+ };
139
+
140
+
141
+ struct base_flag
142
+ {
143
+ enum type : int {
144
+ string = 2,
145
+ number = 4,
146
+ bigint = 8,
147
+ mask_key = string | number | bigint,
148
+ mask_val = string
149
+ };
150
+ int val{};
151
+
152
+ static inline base_flag parse_key(const Napi::Value& arg0) {
153
+ return {arg0.As<Napi::Number>().Int32Value() & mask_key};
154
+ }
155
+
156
+ static inline base_flag parse_value(const value_mode& mode,
157
+ const Napi::Value& arg0) {
158
+ return {arg0.As<Napi::Number>().Int32Value() & mask_val};
159
+ }
160
+
161
+ static inline base_flag parse_value(const Napi::Value& arg0) {
162
+ return {arg0.As<Napi::Number>().Int32Value() & mask_val};
163
+ }
164
+ };
165
+
166
+ static inline key_mode parse_key_mode(Napi::Env env, const Napi::Value& arg0, base_flag& key_flag)
167
+ {
168
+ key_mode mode{};
169
+ if (arg0.IsBigInt()) {
170
+ bool lossless;
171
+ auto value = arg0.As<Napi::BigInt>().Int64Value(&lossless);
172
+ if (!lossless) {
173
+ throw Napi::Error::New(env, "BigInt value lossless conversion failed");
174
+ }
175
+ mode.val = static_cast<int>(value);
176
+ if (mode.val & key_mode::ordinal) {
177
+ // только если цифровой key_flag не был задан
178
+ if (key_flag.val <= base_flag::string) {
179
+ key_flag.val = base_flag::bigint;
180
+ }
181
+ }
182
+ } else if (arg0.IsNumber()) {
183
+ mode = key_mode::parse(arg0);
184
+ if (mode.val & key_mode::ordinal) {
185
+ // только если цифровой key_flag не был задан
186
+ if (key_flag.val <= base_flag::string) {
187
+ key_flag.val = base_flag::number;
188
+ }
189
+ }
190
+ } else {
191
+ throw Napi::Error::New(env, "Invalid argument type for key mode");
192
+ }
193
+ return mode;
194
+ }
195
+
196
+ struct db_mode
197
+ {
198
+ enum type : int {
199
+ create = MDBX_CREATE,
200
+ accede = MDBX_ACCEDE,
201
+ mask = MDBX_CREATE | MDBX_ACCEDE
202
+ };
203
+ int val{};
204
+
205
+ static inline db_mode parse(const txn_mode& mode, const Napi::Value& arg0) {
206
+ db_mode rc{arg0.As<Napi::Number>().Int32Value() & mask};
207
+ if ((mode.val & txn_mode::ro) && (rc.val & db_mode::create)) {
208
+ throw std::runtime_error("create DB in read-only transaction");
209
+ }
210
+ return rc;
211
+ }
212
+ };
213
+
214
+ static inline auto parse_cursor_mode(const Napi::Value& arg0) {
215
+ using move_operation = mdbx::cursor::move_operation;
216
+ if (arg0.IsString()) {
217
+ std::string mode = arg0.As<Napi::String>().Utf8Value();
218
+ if (mode == "first") return move_operation::first;
219
+ if (mode == "last") return move_operation::last;
220
+ if (mode == "next") return move_operation::next;
221
+ if (mode == "prev") return move_operation::previous;
222
+ if (mode == "keyLesser" || mode == "key_lesser_than")
223
+ return move_operation::key_lesser_than;
224
+ if (mode == "keyLesserOrEqual" || mode == "key_lesser_or_equal")
225
+ return move_operation::key_lesser_or_equal;
226
+ if (mode == "keyEqual" || mode == "key_equal")
227
+ return move_operation::key_equal;
228
+ if (mode == "keyGreaterOrEqual" || mode == "key_greater_or_equal")
229
+ return move_operation::key_greater_or_equal;
230
+ if (mode == "keyGreater" || mode == "key_greater_than")
231
+ return move_operation::key_greater_than;
232
+ // Если не найдено, используем по умолчанию
233
+ return move_operation::key_greater_or_equal;
234
+ }
235
+ return static_cast<move_operation>(
236
+ arg0.As<Napi::Number>().Int32Value());
237
+ }
238
+
239
+ } // namespace mdbxmou
@@ -0,0 +1,194 @@
1
+ #pragma once
2
+
3
+ #include "typemou.hpp"
4
+
5
+ namespace mdbxmou {
6
+
7
+ class valuemou
8
+ : public mdbx::slice
9
+ {
10
+ public:
11
+ valuemou() = default;
12
+
13
+ valuemou(const mdbx::slice& arg0) noexcept
14
+ : mdbx::slice{arg0}
15
+ { }
16
+
17
+ valuemou(const Napi::Buffer<char>& arg0) noexcept
18
+ : mdbx::slice{arg0.Data(), arg0.Length()}
19
+ { }
20
+
21
+ valuemou(const buffer_type& arg0) noexcept
22
+ : mdbx::slice{arg0.data(), arg0.size()}
23
+ { }
24
+
25
+ valuemou(const Napi::Buffer<char>& arg0, buffer_type& mem)
26
+ {
27
+ auto ptr = arg0.Data();
28
+ mem.assign(ptr, ptr + arg0.Length());
29
+ assign(mem.data(), mem.size());
30
+ }
31
+
32
+ valuemou(const Napi::String& arg0,
33
+ const Napi::Env& env, buffer_type& mem)
34
+ {
35
+ size_t length;
36
+ auto status =
37
+ napi_get_value_string_utf8(env, arg0, nullptr, 0, &length);
38
+ if (status != napi_ok) {
39
+ throw Napi::Error::New(env, "napi_get_value_string_utf8 length");
40
+ }
41
+
42
+ mem.reserve(length + 1);
43
+ mem.resize(length);
44
+
45
+ status = napi_get_value_string_utf8(
46
+ env, arg0, mem.data(), mem.capacity(), nullptr);
47
+ if (status != napi_ok) {
48
+ throw Napi::Error::New(env, "napi_get_value_string_utf8 copyout");
49
+ }
50
+
51
+ assign(mem.data(), mem.size());
52
+ }
53
+
54
+ static inline valuemou from(const Napi::Value& arg0,
55
+ const Napi::Env& env, buffer_type& mem)
56
+ {
57
+ if (arg0.IsBuffer()) {
58
+ return {arg0.As<Napi::Buffer<char>>()};
59
+ } else if (!arg0.IsString()) {
60
+ throw Napi::Error::New(env, "unsupported value");
61
+ }
62
+ return {arg0.As<Napi::String>(), env, mem};
63
+ }
64
+
65
+ Napi::Value to_string(const Napi::Env& env) const
66
+ {
67
+ return Napi::String::New(env,
68
+ char_ptr(), length());
69
+ }
70
+
71
+ Napi::Value to_buffer(const Napi::Env& env) const
72
+ {
73
+ return Napi::Buffer<char>::Copy(env,
74
+ char_ptr(), length());
75
+ }
76
+ };
77
+
78
+ class keymou final
79
+ : public valuemou
80
+ {
81
+ public:
82
+ keymou() = default;
83
+
84
+ keymou(const valuemou& arg0) noexcept
85
+ : valuemou{arg0}
86
+ { }
87
+
88
+ keymou(const mdbx::slice& arg0) noexcept
89
+ : valuemou{arg0}
90
+ { }
91
+
92
+ keymou(const Napi::Buffer<char>& arg0)
93
+ : valuemou{arg0}
94
+ { }
95
+
96
+ keymou(const buffer_type& arg0) noexcept
97
+ : valuemou{arg0}
98
+ { }
99
+
100
+ keymou(const std::uint64_t& arg0) noexcept
101
+ : valuemou{mdbx::slice{&arg0, sizeof(arg0)}}
102
+ { }
103
+
104
+ keymou(const Napi::Buffer<char>& arg0, buffer_type& mem)
105
+ : valuemou{arg0, mem}
106
+ { }
107
+
108
+ keymou(const Napi::String& arg0,
109
+ const Napi::Env& env, buffer_type& mem)
110
+ : valuemou{arg0, env, mem}
111
+ { }
112
+
113
+ keymou(const Napi::Number& arg0, std::uint64_t& mem)
114
+ {
115
+ auto value = arg0.Int64Value();
116
+ if (value < 0) {
117
+ throw std::runtime_error("Number negative");
118
+ }
119
+ mem = static_cast<std::uint64_t>(value);
120
+ assign(&mem, sizeof(mem));
121
+ }
122
+
123
+ keymou(const Napi::Number& arg0,
124
+ const Napi::Env& env, std::uint64_t& mem)
125
+ {
126
+ auto value = arg0.Int64Value();
127
+ if (value < 0) {
128
+ throw Napi::Error::New(env, "Number negative");
129
+ }
130
+ mem = static_cast<std::uint64_t>(value);
131
+ assign(&mem, sizeof(mem));
132
+ }
133
+
134
+ keymou(const Napi::BigInt& arg0,std::uint64_t& mem)
135
+ {
136
+ bool looseless;
137
+ mem = arg0.Uint64Value(&looseless);
138
+ if (!looseless) {
139
+ throw std::runtime_error("BigInt !looseless");
140
+ }
141
+ assign(&mem, sizeof(mem));
142
+ }
143
+
144
+ keymou(const Napi::BigInt& arg0,
145
+ const Napi::Env& env, std::uint64_t& mem)
146
+ {
147
+ bool looseless;
148
+ mem = arg0.Uint64Value(&looseless);
149
+ if (!looseless) {
150
+ throw Napi::Error::New(env, "BigInt !looseless");
151
+ }
152
+ assign(&mem, sizeof(mem));
153
+ }
154
+
155
+ static inline keymou from(const Napi::Value& arg0,
156
+ const Napi::Env& env, buffer_type& mem)
157
+ {
158
+ return {valuemou::from(arg0, env, mem)};
159
+ }
160
+
161
+ static inline keymou from(const Napi::Value& arg0,
162
+ const Napi::Env& env, std::uint64_t& mem)
163
+ {
164
+ if (arg0.IsBigInt()) {
165
+ return {arg0.As<Napi::BigInt>(), env, mem};
166
+ } else if (!arg0.IsNumber()) {
167
+ throw Napi::Error::New(env, "key must be a Number or BigInt");
168
+ }
169
+ return {arg0.As<Napi::Number>(), env, mem};
170
+ }
171
+
172
+ static inline keymou from(const Napi::Value& arg0,
173
+ const Napi::Env& env, buffer_type& buf, std::uint64_t& num)
174
+ {
175
+ if (arg0.IsBuffer() || arg0.IsString()) {
176
+ return from(arg0, env, buf);
177
+ } else if (!(arg0.IsNumber() || arg0.IsBigInt())) {
178
+ throw Napi::Error::New(env, "key must be a Buffer,String,Number or BigInt");
179
+ }
180
+ return from(arg0, env, num);
181
+ }
182
+
183
+ Napi::Value to_number(const Napi::Env& env) const
184
+ {
185
+ return Napi::Number::New(env, as_int64());
186
+ }
187
+
188
+ Napi::Value to_bigint(const Napi::Env& env) const
189
+ {
190
+ return Napi::BigInt::New(env, as_uint64());
191
+ }
192
+ };
193
+
194
+ } // mdbxmou
package/test/async.js ADDED
@@ -0,0 +1,67 @@
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 = "async-test-db";
9
+ await fs.promises.rm(testPath, { recursive: true, force: true }).catch(() => {});
10
+
11
+ // Создаем среду с параметрами и количеством worker'ов
12
+ const envOptions = {
13
+ path: testPath,
14
+ envFlag: MDBX_Param.envFlag.nostickythreads
15
+ };
16
+ const env = new MDBX_Async_Env(1);
17
+
18
+ // Обработка сигналов для корректного завершения
19
+ const cleanup = async () => {
20
+ console.log("\nReceived interrupt signal, cleaning up...");
21
+ try {
22
+ await env.terminate();
23
+ console.log("Cleanup completed");
24
+ } catch (e) {
25
+ console.error("Cleanup error:", e.message);
26
+ }
27
+ process.exit(0);
28
+ };
29
+
30
+ process.on('SIGINT', cleanup);
31
+ process.on('SIGTERM', cleanup);
32
+
33
+ try {
34
+ await env.open({ path: testPath });
35
+
36
+ const { keyMode } = MDBX_Param;
37
+
38
+ // write txn
39
+ const w = await env.startWrite();
40
+ const dbi = await w.openMap({ keyMode: keyMode.ordinal, create: true });
41
+ await dbi.put(1n, "one");
42
+ await dbi.put(2n, "two");
43
+ await w.commit();
44
+
45
+ // read txn – может уйти в другой worker
46
+ const r = await env.startRead();
47
+ const dbi2 = await r.openMap({ keyMode: keyMode.ordinal });
48
+ const v = await dbi2.get(2n);
49
+ console.log("get(2) =", v);
50
+ await r.commit();
51
+
52
+ await env.close();
53
+ console.log("Database closed");
54
+
55
+ // Завершаем все worker'ы
56
+ await env.terminate();
57
+ console.log("Workers terminated");
58
+ } catch (error) {
59
+ console.error("Test failed:", error);
60
+ try {
61
+ await env.terminate();
62
+ } catch (e) {
63
+ console.error("Cleanup error:", e.message);
64
+ }
65
+ process.exit(1);
66
+ }
67
+ })();
package/test/e3.js ADDED
@@ -0,0 +1,38 @@
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 db_dir = 'e3';
9
+
10
+ await fs.promises.rm(db_dir, { recursive: true, force: true });
11
+
12
+ console.log("MDBX_Param:", MDBX_Param);
13
+ // получаем константы
14
+ const { keyMode } = MDBX_Param;
15
+
16
+ const db = new MDBX_Env();
17
+
18
+ console.log('Opening database...');
19
+
20
+ await db.open({
21
+ path: db_dir
22
+ });
23
+
24
+ console.log('Start write');
25
+ const count = 100000;
26
+ for (let i = 0; i < count; i++) {
27
+ const txn = db.startWrite();
28
+ const dbi = txn.createMap(keyMode.ordinal);
29
+ dbi.put(i, `value_${i}`);
30
+ txn.commit();
31
+ }
32
+
33
+ console.log('Write finish');
34
+
35
+ await db.close();
36
+ }
37
+
38
+ test().catch(console.error);
package/test/e4.js ADDED
@@ -0,0 +1,89 @@
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 path4 = 'e4';
9
+ const path5 = 'e5';
10
+
11
+ console.log("MDBX_Param:", MDBX_Param);
12
+
13
+ await Promise.all([
14
+ fs.promises.rm(path4, { recursive: true, force: true }),
15
+ fs.promises.rm(path5, { recursive: true, force: true })
16
+ ]);
17
+
18
+ const db4 = new MDBX_Env();
19
+ const db5 = new MDBX_Env();
20
+
21
+ console.log('Opening database...');
22
+
23
+ const { valueFlag } = MDBX_Param;
24
+ await Promise.all([
25
+ db4.open({
26
+ path: path4,
27
+ valueFlag: valueFlag.string
28
+ }),
29
+ db5.open({
30
+ path: path5,
31
+ })
32
+ ]);
33
+
34
+ console.log('Start write test...');
35
+ const count = 10;
36
+ const { keyMode } = MDBX_Param;
37
+ const txn = db4.startWrite();
38
+ // при изменении типа ключей надо указывать MDBX_CREATE если базы еще нет
39
+ const dbi = txn.createMap(keyMode.ordinal);
40
+ for (let i = 0; i < count; i++) {
41
+ dbi.put(i, `value_${i}`);
42
+ }
43
+ txn.commit();
44
+ console.log('Start write finish');
45
+
46
+ await Promise.all([await db4.close(), await db5.close()]);
47
+
48
+ //await db.copyTo('e4_copy_async');
49
+
50
+ await db4.open({
51
+ path: path4,
52
+ valueFlag: valueFlag.string
53
+ });
54
+
55
+ let val = "";
56
+ {
57
+ const txn = db4.startRead();
58
+ // для read транакций не нужно указывать MDBX_CREATE иначе будет Permission denied
59
+ const dbi = txn.openMap(BigInt(keyMode.ordinal));
60
+ const stat = dbi.stat();
61
+ for (let i = 0; i < count; i++) {
62
+ val = dbi.get(i);
63
+ }
64
+ console.log('last value:', val.toString());
65
+ console.log('stat:', JSON.stringify(stat));
66
+ txn.commit();
67
+ }
68
+
69
+ {
70
+ const txn = db4.startRead();
71
+ const dbi = txn.openMap(BigInt(keyMode.ordinal));
72
+ dbi.forEach((key, value) => {
73
+ console.log(key, value);
74
+ });
75
+ txn.commit();
76
+ }
77
+
78
+
79
+ const { queryMode, dbMode, keyFlag } = MDBX_Param;
80
+ const result = await db4.query([
81
+ { dbMode: dbMode.accede, keyMode: keyMode.ordinal, mode: queryMode.get, item: [{ key: 0 }, { key: 1n }, { key: 2n }] },
82
+ { dbMode: dbMode.accede, keyMode: keyMode.ordinal, mode: queryMode.get, item: [{ key: 3n }, { key: 4n }, { key: 5n }] }
83
+ ]);
84
+ console.log('query', JSON.stringify(result));
85
+
86
+ await db4.close();
87
+ }
88
+
89
+ test().catch(console.error);