mdbxmou 0.2.2 → 0.2.5
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.
- package/README.md +36 -16
- package/build.js +19 -10
- package/lib/async.d.cts +69 -0
- package/lib/async.d.mts +65 -0
- package/lib/async.mjs +7 -0
- package/lib/index.d.mts +7 -0
- package/lib/index.mjs +12 -0
- package/lib/mdbx_worker.js +24 -8
- package/lib/nativemou.d.cts +4 -0
- package/lib/nativemou.d.mts +5 -0
- package/lib/types.d.ts +260 -0
- package/package.json +41 -1
- package/src/async/envmou_async.cpp +450 -0
- package/src/async/envmou_async.hpp +116 -0
- package/src/envmou.cpp +1 -1
- package/src/txnmou.cpp +21 -120
- package/src/txnmou.hpp +18 -71
package/src/txnmou.cpp
CHANGED
|
@@ -12,11 +12,6 @@ void txnmou::init(const char *class_name, Napi::Env env) {
|
|
|
12
12
|
InstanceMethod("openMap", &txnmou::open_map),
|
|
13
13
|
InstanceMethod("createMap", &txnmou::create_map),
|
|
14
14
|
InstanceMethod("isActive", &txnmou::is_active),
|
|
15
|
-
InstanceMethod("isTopLevel", &txnmou::is_top_level),
|
|
16
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
17
|
-
InstanceMethod("startTransaction", &txnmou::start_transaction),
|
|
18
|
-
InstanceMethod("getChildrenCount", &txnmou::get_children_count),
|
|
19
|
-
#endif
|
|
20
15
|
});
|
|
21
16
|
|
|
22
17
|
ctor = Napi::Persistent(func);
|
|
@@ -28,22 +23,14 @@ Napi::Value txnmou::commit(const Napi::CallbackInfo& info) {
|
|
|
28
23
|
|
|
29
24
|
try {
|
|
30
25
|
check();
|
|
31
|
-
|
|
32
|
-
// Проверяем активные дочерние транзакции
|
|
33
|
-
cleanup_children();
|
|
34
|
-
|
|
35
|
-
if (has_active_children()) {
|
|
36
|
-
throw std::runtime_error("txn: active child exist");
|
|
37
|
-
}
|
|
38
|
-
#endif // MDBX_TXN_HAS_CHILD
|
|
26
|
+
|
|
39
27
|
auto rc = mdbx_txn_commit(*this);
|
|
40
28
|
if (rc != MDBX_SUCCESS) {
|
|
41
29
|
throw Napi::Error::New(env, std::string("txn: ") + mdbx_strerror(rc));
|
|
42
30
|
}
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
txn_.reset();
|
|
32
|
+
dec_counter();
|
|
33
|
+
txn_.release();
|
|
47
34
|
} catch (const std::exception& e) {
|
|
48
35
|
throw Napi::Error::New(env, e.what());
|
|
49
36
|
}
|
|
@@ -56,27 +43,14 @@ Napi::Value txnmou::abort(const Napi::CallbackInfo& info) {
|
|
|
56
43
|
|
|
57
44
|
try {
|
|
58
45
|
check();
|
|
59
|
-
|
|
60
|
-
// Сначала отменяем все дочерние транзакции
|
|
61
|
-
cleanup_children();
|
|
62
|
-
|
|
63
|
-
for (const auto& child : children_) {
|
|
64
|
-
if (child && child->txn_ && !child->is_committed_ && !child->is_aborted_) {
|
|
65
|
-
try {
|
|
66
|
-
child->abort(info);
|
|
67
|
-
} catch (...) {
|
|
68
|
-
// Игнорируем ошибки при abort дочерних
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
#endif // MDBX_TXN_HAS_CHILD
|
|
46
|
+
|
|
73
47
|
auto rc = mdbx_txn_abort(*this);
|
|
74
48
|
if (rc != MDBX_SUCCESS) {
|
|
75
49
|
throw Napi::Error::New(env, std::string("txn: ") + mdbx_strerror(rc));
|
|
76
50
|
}
|
|
77
51
|
|
|
78
|
-
|
|
79
|
-
txn_.
|
|
52
|
+
dec_counter();
|
|
53
|
+
txn_.release();
|
|
80
54
|
} catch (const std::exception& e) {
|
|
81
55
|
throw Napi::Error::New(env, e.what());
|
|
82
56
|
}
|
|
@@ -84,6 +58,14 @@ Napi::Value txnmou::abort(const Napi::CallbackInfo& info) {
|
|
|
84
58
|
return env.Undefined();
|
|
85
59
|
}
|
|
86
60
|
|
|
61
|
+
// Уменьшает счетчик транзакций
|
|
62
|
+
void txnmou::dec_counter() noexcept
|
|
63
|
+
{
|
|
64
|
+
if (env_) {
|
|
65
|
+
--(*env_);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
87
69
|
Napi::Value txnmou::get_dbi(const Napi::CallbackInfo& info, db_mode db_mode)
|
|
88
70
|
{
|
|
89
71
|
Napi::Env env = info.Env();
|
|
@@ -135,16 +117,15 @@ Napi::Value txnmou::get_dbi(const Napi::CallbackInfo& info, db_mode db_mode)
|
|
|
135
117
|
|
|
136
118
|
check();
|
|
137
119
|
|
|
138
|
-
// создаем новый объект dbi
|
|
139
|
-
auto obj = dbimou::ctor.New({});
|
|
140
|
-
auto ptr = dbimou::Unwrap(obj);
|
|
141
|
-
|
|
142
120
|
MDBX_dbi dbi{};
|
|
143
121
|
auto flags = static_cast<MDBX_db_flags_t>(db_mode.val|key_mode.val|value_mode.val);
|
|
144
122
|
auto rc = mdbx_dbi_open(*this, db_name.empty() ? nullptr : db_name.c_str(), flags, &dbi);
|
|
145
123
|
if (rc != MDBX_SUCCESS) {
|
|
146
124
|
throw std::runtime_error(std::string("mdbx_dbi_open ") + mdbx_strerror(rc));
|
|
147
125
|
}
|
|
126
|
+
// создаем новый объект dbi
|
|
127
|
+
auto obj = dbimou::ctor.New({});
|
|
128
|
+
auto ptr = dbimou::Unwrap(obj);
|
|
148
129
|
ptr->attach(dbi, db_mode, key_mode,
|
|
149
130
|
value_mode, key_flag, value_flag);
|
|
150
131
|
return obj;
|
|
@@ -159,96 +140,16 @@ Napi::Value txnmou::get_dbi(const Napi::CallbackInfo& info, db_mode db_mode)
|
|
|
159
140
|
|
|
160
141
|
Napi::Value txnmou::is_active(const Napi::CallbackInfo& info) {
|
|
161
142
|
Napi::Env env = info.Env();
|
|
162
|
-
|
|
163
|
-
return Napi::Boolean::New(env, active);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
Napi::Value txnmou::is_top_level(const Napi::CallbackInfo& info) {
|
|
167
|
-
Napi::Env env = info.Env();
|
|
168
|
-
return Napi::Boolean::New(env, parent_ == nullptr);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
172
|
-
|
|
173
|
-
Napi::Value txnmou::start_transaction(const Napi::CallbackInfo& info) {
|
|
174
|
-
Napi::Env env = info.Env();
|
|
175
|
-
|
|
176
|
-
// Создаем новый объект txnmou для дочерней транзакции
|
|
177
|
-
auto child_obj = ctor.New({});
|
|
178
|
-
auto child_wrapper = txnmou::Unwrap(child_obj);
|
|
179
|
-
|
|
180
|
-
int rc{MDBX_SUCCESS};
|
|
181
|
-
try {
|
|
182
|
-
check();
|
|
183
|
-
|
|
184
|
-
MDBX_txn* child_txn;
|
|
185
|
-
auto rc = mdbx_txn_begin(*env_, txn_.get(), flags_, &child_txn);
|
|
186
|
-
if (rc != MDBX_SUCCESS) {
|
|
187
|
-
std::string flag_name = (flags_ == MDBX_TXN_RDONLY) ? "read" : "write";
|
|
188
|
-
throw Napi::Error::New(env, std::string("txn ") + flag_name + ": " + mdbx_strerror(rc));
|
|
189
|
-
}
|
|
190
|
-
child_wrapper->attach(*env_, child_txn, flags_, this);
|
|
191
|
-
} catch (const std::exception& e) {
|
|
192
|
-
throw Napi::Error::New(env, e.what());
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return child_obj;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
Napi::Value txnmou::get_children_count(const Napi::CallbackInfo& info) {
|
|
199
|
-
Napi::Env env = info.Env();
|
|
200
|
-
cleanup_children();
|
|
201
|
-
|
|
202
|
-
size_t active_count = 0;
|
|
203
|
-
for (const auto& child : children_) {
|
|
204
|
-
if (child && child->txn_ && !child->is_committed_ && !child->is_aborted_) {
|
|
205
|
-
active_count++;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return Napi::Number::New(env, static_cast<double>(active_count));
|
|
143
|
+
return Napi::Boolean::New(env, txn_ != nullptr);
|
|
210
144
|
}
|
|
211
145
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
void txnmou::attach(envmou& env, MDBX_txn* txn,
|
|
215
|
-
txn_mode mode, txnmou* parent)
|
|
146
|
+
void txnmou::attach(envmou& env, MDBX_txn* txn, txn_mode mode)
|
|
216
147
|
{
|
|
217
|
-
// увеличиваем счетчик транзакций в env
|
|
218
148
|
env_ = &env;
|
|
219
|
-
|
|
220
|
-
if (parent == nullptr) {
|
|
221
|
-
// Если родительская транзакция не указана, увеличиваем счетчик
|
|
222
|
-
++(*env_);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
parent_ = parent;
|
|
226
149
|
mode_ = mode;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
231
|
-
if (parent) {
|
|
232
|
-
parent->push_back(this);
|
|
233
|
-
}
|
|
234
|
-
#endif
|
|
150
|
+
|
|
151
|
+
++(*env_);
|
|
235
152
|
txn_.reset(txn);
|
|
236
153
|
}
|
|
237
154
|
|
|
238
|
-
void txnmou::free_txn::operator()(MDBX_txn* txn) const noexcept {
|
|
239
|
-
if (!that.is_committed_ && !that.is_aborted_) {
|
|
240
|
-
// Автоматический abort при деструкции
|
|
241
|
-
auto rc = mdbx_txn_abort(that);
|
|
242
|
-
if (rc != MDBX_SUCCESS) {
|
|
243
|
-
fprintf(stderr, "mdbx_txn_abort code: %d, msg: %s\n", rc, mdbx_strerror(rc));
|
|
244
|
-
}
|
|
245
|
-
that.is_aborted_ = true;
|
|
246
|
-
}
|
|
247
|
-
// уменьшаем счетчик транзакций (только родительских)
|
|
248
|
-
if (that.parent_ == nullptr) {
|
|
249
|
-
//fprintf(stderr, "free_txn: --env\n");
|
|
250
|
-
--(*that.env_);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
155
|
} // namespace mdbxmou
|
package/src/txnmou.hpp
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
#include "dbimou.hpp"
|
|
4
4
|
|
|
5
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
6
|
-
#include <vector>
|
|
7
|
-
#endif
|
|
8
|
-
|
|
9
5
|
namespace mdbxmou {
|
|
10
6
|
|
|
11
7
|
class envmou;
|
|
@@ -15,73 +11,26 @@ class txnmou final
|
|
|
15
11
|
{
|
|
16
12
|
private:
|
|
17
13
|
envmou* env_{nullptr};
|
|
18
|
-
|
|
14
|
+
|
|
15
|
+
// Простой deleter
|
|
19
16
|
struct free_txn {
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
void operator()(MDBX_txn* txn) const noexcept {
|
|
18
|
+
mdbx_txn_abort(txn);
|
|
19
|
+
}
|
|
22
20
|
};
|
|
23
|
-
|
|
24
|
-
free_txn erase_{*this};
|
|
25
|
-
std::unique_ptr<MDBX_txn, free_txn> txn_{nullptr, erase_};
|
|
26
|
-
|
|
27
|
-
// Иерархия транзакций
|
|
28
|
-
txnmou* parent_{nullptr};
|
|
29
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
30
|
-
std::vector<txnmou*> children_{};
|
|
31
|
-
#endif
|
|
32
|
-
|
|
33
|
-
// Флаг для отслеживания состояния
|
|
34
|
-
bool is_committed_{};
|
|
35
|
-
bool is_aborted_{};
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
std::unique_ptr<MDBX_txn, free_txn> txn_{};
|
|
38
23
|
txn_mode mode_{};
|
|
39
24
|
|
|
40
|
-
void
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
throw std::runtime_error("txn: already committed");
|
|
44
|
-
if (is_aborted_)
|
|
45
|
-
throw std::runtime_error("txn: already aborted");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
void check() const
|
|
49
|
-
{
|
|
50
|
-
check_valid();
|
|
51
|
-
|
|
52
|
-
if (!txn_)
|
|
53
|
-
throw std::runtime_error("txn: not initialized");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
57
|
-
// Проверка активных дочерних транзакций
|
|
58
|
-
bool has_active_children() const {
|
|
59
|
-
for (const auto& child : children_) {
|
|
60
|
-
if (child && child->txn_ && !child->is_committed_ && !child->is_aborted_) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
25
|
+
void check() const {
|
|
26
|
+
if (!txn_) {
|
|
27
|
+
throw std::runtime_error("txn: inactive");
|
|
63
28
|
}
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Очистка завершенных дочерних транзакций
|
|
68
|
-
void cleanup_children() {
|
|
69
|
-
children_.erase(
|
|
70
|
-
std::remove_if(children_.begin(), children_.end(),
|
|
71
|
-
[](const txnmou* child) {
|
|
72
|
-
return !child || child->is_committed_ || child->is_aborted_;
|
|
73
|
-
}),
|
|
74
|
-
children_.end()
|
|
75
|
-
);
|
|
76
29
|
}
|
|
77
30
|
|
|
78
|
-
//
|
|
79
|
-
|
|
31
|
+
// Уменьшает счетчик транзакций
|
|
32
|
+
void dec_counter() noexcept;
|
|
80
33
|
|
|
81
|
-
void push_back(txnmou* child) {
|
|
82
|
-
children_.push_back(child);
|
|
83
|
-
}
|
|
84
|
-
#endif
|
|
85
34
|
Napi::Value get_dbi(const Napi::CallbackInfo&, db_mode);
|
|
86
35
|
|
|
87
36
|
public:
|
|
@@ -91,9 +40,14 @@ public:
|
|
|
91
40
|
: Napi::ObjectWrap<txnmou>(info)
|
|
92
41
|
{ }
|
|
93
42
|
|
|
43
|
+
~txnmou() {
|
|
44
|
+
if (txn_) {
|
|
45
|
+
dec_counter();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
94
49
|
static void init(const char *class_name, Napi::Env env);
|
|
95
50
|
|
|
96
|
-
// Основные операции (только синхронные)
|
|
97
51
|
Napi::Value commit(const Napi::CallbackInfo&);
|
|
98
52
|
Napi::Value abort(const Napi::CallbackInfo&);
|
|
99
53
|
Napi::Value open_map(const Napi::CallbackInfo& info) {
|
|
@@ -107,16 +61,9 @@ public:
|
|
|
107
61
|
return txn_.get();
|
|
108
62
|
}
|
|
109
63
|
|
|
110
|
-
#ifdef MDBX_TXN_HAS_CHILD
|
|
111
|
-
// Работа с вложенными транзакциями
|
|
112
|
-
Napi::Value start_transaction(const Napi::CallbackInfo&);
|
|
113
|
-
Napi::Value get_children_count(const Napi::CallbackInfo&);
|
|
114
|
-
#endif
|
|
115
64
|
Napi::Value is_active(const Napi::CallbackInfo&);
|
|
116
|
-
Napi::Value is_top_level(const Napi::CallbackInfo&);
|
|
117
65
|
|
|
118
|
-
void attach(envmou& env, MDBX_txn* txn,
|
|
119
|
-
txn_mode mode, txnmou* parent = nullptr);
|
|
66
|
+
void attach(envmou& env, MDBX_txn* txn, txn_mode mode);
|
|
120
67
|
};
|
|
121
68
|
|
|
122
69
|
} // namespace mdbxmou
|