mdbxmou 0.3.11 → 0.3.13
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 +113 -11
- package/deps/libmdbx/ChangeLog.md +44 -0
- package/deps/libmdbx/SECURITY.md +18 -0
- package/deps/libmdbx/VERSION.json +1 -1
- package/deps/libmdbx/mdbx.c +121 -63
- package/deps/libmdbx/mdbx.c++ +2 -2
- package/deps/libmdbx/mdbx_chk.c +2 -2
- package/deps/libmdbx/mdbx_copy.c +2 -2
- package/deps/libmdbx/mdbx_drop.c +2 -2
- package/deps/libmdbx/mdbx_dump.c +5 -5
- package/deps/libmdbx/mdbx_load.c +24 -23
- package/deps/libmdbx/mdbx_stat.c +2 -3
- package/lib/async.d.mts +6 -4
- package/lib/types.d.ts +17 -2
- package/package.json +2 -1
- package/src/async/envmou_keys.cpp +1 -1
- package/src/async/envmou_query.cpp +14 -13
- package/src/convmou.cpp +17 -0
- package/src/convmou.hpp +4 -8
- package/src/cursormou.cpp +2 -1
- package/src/cursormou.hpp +1 -0
- package/src/dbimou.cpp +71 -18
- package/src/dbimou.hpp +3 -1
- package/src/modulemou.cpp +14 -0
- package/src/querymou.cpp +15 -15
- package/src/querymou.hpp +3 -1
- package/src/txnmou.cpp +3 -3
- package/src/typemou.hpp +85 -5
- package/src/valuemou.hpp +62 -83
- package/deps/libmdbx/.github/workflows/ci-android.yml +0 -38
- package/deps/libmdbx/.github/workflows/ci-mingw.yml +0 -40
- package/deps/libmdbx/.github/workflows/ci-posix.yml +0 -34
- package/deps/libmdbx/.github/workflows/ci-wincxx.yml +0 -45
- package/deps/libmdbx/.github/workflows/ci-windows.yml +0 -32
- package/deps/libmdbx/ci.sh +0 -86
- package/deps/libmdbx/packages/archlinux/.SRCINFO +0 -16
- package/deps/libmdbx/packages/archlinux/PKGBUILD +0 -38
- package/deps/libmdbx/packages/buildroot/0001-package-libmdbx.patch +0 -75
package/deps/libmdbx/mdbx_stat.c
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
/// \copyright SPDX-License-Identifier: Apache-2.0
|
|
19
19
|
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2026
|
|
20
20
|
|
|
21
|
-
#define MDBX_BUILD_SOURCERY
|
|
21
|
+
#define MDBX_BUILD_SOURCERY a575a490fc080ca11e89ff6db9f0bd38aa830959905998cac0e45274b9e6bb0e_v0_13_12_0_gf619d43d
|
|
22
22
|
|
|
23
23
|
#define LIBMDBX_INTERNALS
|
|
24
24
|
#define MDBX_DEPRECATED
|
|
@@ -1499,7 +1499,7 @@ MDBX_INTERNAL int osal_lockfile(mdbx_filehandle_t fd, bool wait);
|
|
|
1499
1499
|
#define MMAP_OPTION_SEMAPHORE 2
|
|
1500
1500
|
MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, const unsigned options,
|
|
1501
1501
|
const pathchar_t *pathname4logging);
|
|
1502
|
-
MDBX_INTERNAL
|
|
1502
|
+
MDBX_INTERNAL void osal_munmap(osal_mmap_t *map);
|
|
1503
1503
|
#define MDBX_MRESIZE_MAY_MOVE 0x00000100
|
|
1504
1504
|
#define MDBX_MRESIZE_MAY_UNMAP 0x00000200
|
|
1505
1505
|
MDBX_INTERNAL int osal_mresize(const int flags, osal_mmap_t *map, size_t size, size_t limit);
|
|
@@ -3516,7 +3516,6 @@ int main(int argc, char *argv[]) {
|
|
|
3516
3516
|
signal(SIGTERM, signal_handler);
|
|
3517
3517
|
#endif /* !WINDOWS */
|
|
3518
3518
|
|
|
3519
|
-
envname = argv[optind];
|
|
3520
3519
|
envname = argv[optind];
|
|
3521
3520
|
if (!quiet) {
|
|
3522
3521
|
printf("mdbx_stat %s (%s, T-%s)\nRunning for %s...\n", mdbx_version.git.describe, mdbx_version.git.datetime,
|
package/lib/async.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { MDBXDbiStat, MDBXEnvOpenOptions, MDBXKey
|
|
1
|
+
import type { MDBXDbiStat, MDBXEnvOpenOptions, MDBXKey } from "./types.js";
|
|
2
|
+
|
|
3
|
+
type MDBXAsyncValue = Buffer | string;
|
|
2
4
|
|
|
3
5
|
export interface MDBXAsyncMapOpenOptions {
|
|
4
6
|
name?: string;
|
|
@@ -35,15 +37,15 @@ export interface MDBXAsyncDelBatchResultItem {
|
|
|
35
37
|
export declare class MDBX_Async_Dbi {
|
|
36
38
|
readonly meta: MDBXAsyncDbiMeta;
|
|
37
39
|
|
|
38
|
-
put(key: MDBXKey, value:
|
|
40
|
+
put(key: MDBXKey, value: MDBXAsyncValue, flags?: number): Promise<boolean>;
|
|
39
41
|
get(key: MDBXKey): Promise<string | null | undefined>;
|
|
40
42
|
del(key: MDBXKey): Promise<boolean>;
|
|
41
43
|
stat(): Promise<MDBXDbiStat>;
|
|
42
44
|
|
|
43
|
-
forEach(cb: (key: MDBXKey, value:
|
|
45
|
+
forEach(cb: (key: MDBXKey, value: MDBXAsyncValue, index: number) => void): Promise<void>;
|
|
44
46
|
|
|
45
47
|
getBatch(keys: MDBXKey[]): Promise<MDBXAsyncGetBatchResultItem[]>;
|
|
46
|
-
putBatch(items: Array<{ key: MDBXKey; value:
|
|
48
|
+
putBatch(items: Array<{ key: MDBXKey; value: MDBXAsyncValue }>, flags?: number): Promise<MDBXAsyncPutBatchResultItem[]>;
|
|
47
49
|
delBatch(keys: MDBXKey[]): Promise<MDBXAsyncDelBatchResultItem[]>;
|
|
48
50
|
}
|
|
49
51
|
|
package/lib/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
|
|
3
3
|
export type MDBXKey = Buffer | string | number | bigint;
|
|
4
|
-
export type MDBXValue = Buffer | string;
|
|
4
|
+
export type MDBXValue = Buffer | string | number | bigint;
|
|
5
5
|
|
|
6
6
|
export type MDBXCursorMode =
|
|
7
7
|
| number
|
|
@@ -202,7 +202,7 @@ export interface MDBX_Dbi<K extends MDBXKey = MDBXKey, V extends MDBXValue = MDB
|
|
|
202
202
|
readonly keyFlag: number;
|
|
203
203
|
readonly valueFlag: number;
|
|
204
204
|
|
|
205
|
-
put(txn: MDBX_Txn, key: K, value: MDBXValue): void;
|
|
205
|
+
put(txn: MDBX_Txn, key: K, value: MDBXValue, flags?: number): void;
|
|
206
206
|
get(txn: MDBX_Txn, key: K): V | undefined;
|
|
207
207
|
del(txn: MDBX_Txn, key: K): boolean;
|
|
208
208
|
has(txn: MDBX_Txn, key: K): boolean;
|
|
@@ -224,6 +224,7 @@ export interface MDBX_Dbi<K extends MDBXKey = MDBXKey, V extends MDBXValue = MDB
|
|
|
224
224
|
keys(txn: MDBX_Txn): K[];
|
|
225
225
|
keysFrom(txn: MDBX_Txn, fromKey: K, limit?: number, cursorMode?: MDBXCursorMode): K[];
|
|
226
226
|
getRange(txn: MDBX_Txn, options?: MDBXRangeOptions<K>): MDBXCursorResult<K, V>[];
|
|
227
|
+
getCount(txn: MDBX_Txn, options?: MDBXRangeOptions<K>): number;
|
|
227
228
|
keysRange(txn: MDBX_Txn, options?: MDBXRangeOptions<K>): K[];
|
|
228
229
|
valuesRange(txn: MDBX_Txn, options?: MDBXRangeOptions<K>): V[];
|
|
229
230
|
drop(txn: MDBX_Txn, deleteDb?: boolean): void;
|
|
@@ -264,6 +265,7 @@ export interface MDBXQueryRequest {
|
|
|
264
265
|
dbi: MDBX_Dbi;
|
|
265
266
|
mode?: number;
|
|
266
267
|
queryMode?: number;
|
|
268
|
+
putFlag?: number;
|
|
267
269
|
item: MDBXQueryItem[];
|
|
268
270
|
}
|
|
269
271
|
|
|
@@ -374,6 +376,8 @@ export interface MDBX_Param {
|
|
|
374
376
|
|
|
375
377
|
readonly valueFlag: {
|
|
376
378
|
readonly string: number;
|
|
379
|
+
readonly number: number;
|
|
380
|
+
readonly bigint: number;
|
|
377
381
|
};
|
|
378
382
|
|
|
379
383
|
readonly dbMode: {
|
|
@@ -389,6 +393,17 @@ export interface MDBX_Param {
|
|
|
389
393
|
readonly del: number;
|
|
390
394
|
};
|
|
391
395
|
|
|
396
|
+
readonly putFlag: {
|
|
397
|
+
readonly noOverwrite: number;
|
|
398
|
+
readonly noDupData: number;
|
|
399
|
+
readonly current: number;
|
|
400
|
+
readonly allDups: number;
|
|
401
|
+
readonly reserve: number;
|
|
402
|
+
readonly append: number;
|
|
403
|
+
readonly appendDup: number;
|
|
404
|
+
readonly multiple: number;
|
|
405
|
+
};
|
|
406
|
+
|
|
392
407
|
readonly cursorMode: {
|
|
393
408
|
readonly first: number;
|
|
394
409
|
readonly last: number;
|
package/package.json
CHANGED
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"e5": "node ./test/e5.js",
|
|
62
62
|
"e7": "node ./test/e7.js",
|
|
63
63
|
"e8": "node ./test/e8.js",
|
|
64
|
+
"e9": "node ./test/e9.js",
|
|
64
65
|
"test:types": "node ./test/types/run.mjs",
|
|
65
66
|
"build": "node build.js",
|
|
66
67
|
"build-dev": "node build-dev.js",
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
},
|
|
69
70
|
"gypfile": true,
|
|
70
71
|
"name": "mdbxmou",
|
|
71
|
-
"version": "0.3.
|
|
72
|
+
"version": "0.3.13",
|
|
72
73
|
"description": "Node bindings for mdbx",
|
|
73
74
|
"repository": {
|
|
74
75
|
"type": "git",
|
|
@@ -67,7 +67,7 @@ void async_keys::Execute()
|
|
|
67
67
|
static Napi::Value write_row(Napi::Env env, const keys_line& row)
|
|
68
68
|
{
|
|
69
69
|
auto& param = row.item;
|
|
70
|
-
convmou conv{row.key_mod, row.key_flag};
|
|
70
|
+
convmou conv{row.key_mod, {}, row.key_flag, {}};
|
|
71
71
|
auto js_arr = Napi::Array::New(env, param.size());
|
|
72
72
|
for (std::uint32_t j = 0; j < param.size(); ++j) {
|
|
73
73
|
const auto& item = param[j];
|
|
@@ -13,9 +13,9 @@ void async_query::Execute()
|
|
|
13
13
|
{
|
|
14
14
|
mdbx::map_handle dbi{req.id};
|
|
15
15
|
auto mode = req.mode;
|
|
16
|
-
if (mode.
|
|
16
|
+
if (mode.is_get()) {
|
|
17
17
|
do_get(txn, dbi, req);
|
|
18
|
-
} else if (mode.
|
|
18
|
+
} else if (mode.is_del()) {
|
|
19
19
|
do_del(txn, dbi, req);
|
|
20
20
|
} else {
|
|
21
21
|
do_put(txn, dbi, req);
|
|
@@ -33,7 +33,7 @@ static Napi::Value write_row(Napi::Env env, const query_line& row)
|
|
|
33
33
|
{
|
|
34
34
|
auto& param = row.item;
|
|
35
35
|
auto mode = row.mode;
|
|
36
|
-
convmou conv{row.key_mod, row.key_flag, row.value_flag};
|
|
36
|
+
convmou conv{row.key_mod, row.val_mod, row.key_flag, row.value_flag};
|
|
37
37
|
auto js_arr = Napi::Array::New(env, param.size());
|
|
38
38
|
for (std::size_t j = 0; j < param.size(); ++j) {
|
|
39
39
|
const auto& item = param[j];
|
|
@@ -43,13 +43,11 @@ static Napi::Value write_row(Napi::Env env, const query_line& row)
|
|
|
43
43
|
keymou{item.key_buf};
|
|
44
44
|
js_item.Set("key", conv.convert_key(env, key));
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
const auto mask{query_mode::get|query_mode::upsert|
|
|
48
|
-
query_mode::update|query_mode::insert_unique};
|
|
49
|
-
if (mode.val & mask)
|
|
50
|
-
{
|
|
46
|
+
if (mode.is_get() || mode.is_write()) {
|
|
51
47
|
auto& val_buf = item.val_buf;
|
|
52
|
-
if (val_buf.empty()) {
|
|
48
|
+
if (is_ordinal(row.val_mod) && mode.is_write() && val_buf.empty()) {
|
|
49
|
+
js_item.Set("value", conv.convert_value(env, valuemou{item.val_num}));
|
|
50
|
+
} else if (val_buf.empty()) {
|
|
53
51
|
js_item.Set("value", env.Null());
|
|
54
52
|
} else {
|
|
55
53
|
js_item.Set("value",
|
|
@@ -58,7 +56,7 @@ static Napi::Value write_row(Napi::Env env, const query_line& row)
|
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
// выдадим флаги удаления и успешности
|
|
61
|
-
if (mode.
|
|
59
|
+
if (mode.is_del()) {
|
|
62
60
|
js_item.Set("found", Napi::Boolean::New(env, item.found));
|
|
63
61
|
}
|
|
64
62
|
js_arr.Set(static_cast<uint32_t>(j), js_item);
|
|
@@ -133,15 +131,18 @@ void async_query::do_get(const txnmou_managed& txn,
|
|
|
133
131
|
void async_query::do_put(txnmou_managed& txn,
|
|
134
132
|
mdbx::map_handle dbi, query_line& arg0)
|
|
135
133
|
{
|
|
136
|
-
auto
|
|
134
|
+
auto flags = static_cast<MDBX_put_flags_t>(
|
|
135
|
+
arg0.mode.write_flags() | arg0.put_flags.val);
|
|
137
136
|
// очищаем put флаги
|
|
138
137
|
auto key_mode = arg0.key_mod;
|
|
139
138
|
for (auto& q : arg0.item)
|
|
140
139
|
{
|
|
141
140
|
auto key = mdbx::is_ordinal(key_mode) ?
|
|
142
141
|
keymou{q.id_buf} : keymou{q.key_buf};
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
valuemou val = is_ordinal(arg0.val_mod) ?
|
|
143
|
+
valuemou{q.val_num} :
|
|
144
|
+
valuemou{q.val_buf};
|
|
145
|
+
mdbx::error::success_or_throw(txn.put(dbi, key, &val, flags));
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
148
|
|
package/src/convmou.cpp
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
#include "convmou.hpp"
|
|
2
|
+
#include "dbimou.hpp"
|
|
2
3
|
|
|
3
4
|
namespace mdbxmou {
|
|
4
5
|
|
|
6
|
+
convmou convmou::for_dbi(const dbimou& dbi) noexcept
|
|
7
|
+
{
|
|
8
|
+
return {
|
|
9
|
+
dbi.get_key_mode(),
|
|
10
|
+
dbi.get_value_mode(),
|
|
11
|
+
dbi.get_key_flag(),
|
|
12
|
+
dbi.get_value_flag()
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
Napi::Value convmou::convert_key(const Napi::Env& env, const keymou& key) const
|
|
6
17
|
{
|
|
7
18
|
if (mdbx::is_ordinal(key_mode_)) {
|
|
@@ -17,6 +28,12 @@ Napi::Value convmou::convert_key(const Napi::Env& env, const keymou& key) const
|
|
|
17
28
|
|
|
18
29
|
Napi::Value convmou::convert_value(const Napi::Env& env, const valuemou& val) const
|
|
19
30
|
{
|
|
31
|
+
if (is_ordinal(value_mode_)) {
|
|
32
|
+
return (value_flag_ & base_flag::bigint) ?
|
|
33
|
+
val.to_bigint(env) :
|
|
34
|
+
val.to_number(env);
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
return (value_flag_ & base_flag::string) ?
|
|
21
38
|
val.to_string(env) :
|
|
22
39
|
val.to_buffer(env);
|
package/src/convmou.hpp
CHANGED
|
@@ -4,20 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
namespace mdbxmou {
|
|
6
6
|
|
|
7
|
+
class dbimou;
|
|
8
|
+
|
|
7
9
|
struct convmou
|
|
8
10
|
{
|
|
9
11
|
key_mode key_mode_{};
|
|
12
|
+
value_mode value_mode_{};
|
|
10
13
|
base_flag key_flag_{};
|
|
11
14
|
base_flag value_flag_{};
|
|
12
15
|
|
|
13
|
-
convmou()
|
|
14
|
-
|
|
15
|
-
convmou(key_mode key_mode, base_flag key_flag,
|
|
16
|
-
base_flag value_flag = {}) noexcept
|
|
17
|
-
: key_mode_{key_mode}
|
|
18
|
-
, key_flag_{key_flag}
|
|
19
|
-
, value_flag_{value_flag}
|
|
20
|
-
{ }
|
|
16
|
+
static convmou for_dbi(const dbimou& dbi) noexcept;
|
|
21
17
|
|
|
22
18
|
Napi::Value convert_key(const Napi::Env& env, const keymou& key) const;
|
|
23
19
|
|
package/src/cursormou.cpp
CHANGED
|
@@ -230,7 +230,8 @@ namespace mdbxmou
|
|
|
230
230
|
keymou::from(info[0], env, key_num_) :
|
|
231
231
|
keymou::from(info[0], env, key_buf_);
|
|
232
232
|
|
|
233
|
-
valuemou val = valuemou::from(info[1], env, val_buf_
|
|
233
|
+
valuemou val = valuemou::from(info[1], env, val_buf_, val_num_,
|
|
234
|
+
is_ordinal(dbi_->get_value_mode()));
|
|
234
235
|
|
|
235
236
|
// Опциональный флаг put_mode (по умолчанию MDBX_UPSERT)
|
|
236
237
|
MDBX_put_flags_t flags = MDBX_UPSERT;
|
package/src/cursormou.hpp
CHANGED
package/src/dbimou.cpp
CHANGED
|
@@ -165,14 +165,13 @@ MDBX_cursor_op range_turn_op(const range_options& options)
|
|
|
165
165
|
return options.reverse ? MDBX_PREV : MDBX_NEXT;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
template<class Fn>
|
|
169
|
+
std::size_t scan_range(dbimou& self, txnmou& txn, const range_options& options, Fn&& fn)
|
|
169
170
|
{
|
|
170
|
-
Napi::Array result = Napi::Array::New(env);
|
|
171
171
|
if (options.limit == 0) {
|
|
172
|
-
return
|
|
172
|
+
return 0;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
auto conv = self.get_convmou();
|
|
176
175
|
auto cursor = self.open_cursor(txn);
|
|
177
176
|
mdbx::slice key{};
|
|
178
177
|
mdbx::slice value{};
|
|
@@ -186,7 +185,7 @@ Napi::Array collect_range(const Napi::Env& env, dbimou& self, txnmou& txn, const
|
|
|
186
185
|
}
|
|
187
186
|
|
|
188
187
|
if (!cursor_get(cursor, range_start_op(options), key, value)) {
|
|
189
|
-
return
|
|
188
|
+
return 0;
|
|
190
189
|
}
|
|
191
190
|
|
|
192
191
|
std::size_t skipped{};
|
|
@@ -201,17 +200,8 @@ Napi::Array collect_range(const Napi::Env& env, dbimou& self, txnmou& txn, const
|
|
|
201
200
|
if (skipped < options.offset) {
|
|
202
201
|
++skipped;
|
|
203
202
|
} else {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
result.Set(index, conv.make_result(env, keymou{key}, valuemou{value}));
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
case range_output::keys:
|
|
210
|
-
result.Set(index, conv.convert_key(env, keymou{key}));
|
|
211
|
-
break;
|
|
212
|
-
case range_output::values:
|
|
213
|
-
result.Set(index, conv.convert_value(env, valuemou{value}));
|
|
214
|
-
break;
|
|
203
|
+
if (fn(keymou{key}, valuemou{value}, index)) {
|
|
204
|
+
break;
|
|
215
205
|
}
|
|
216
206
|
|
|
217
207
|
++index;
|
|
@@ -225,9 +215,39 @@ Napi::Array collect_range(const Napi::Env& env, dbimou& self, txnmou& txn, const
|
|
|
225
215
|
}
|
|
226
216
|
}
|
|
227
217
|
|
|
218
|
+
return index;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
Napi::Array collect_range(const Napi::Env& env, dbimou& self, txnmou& txn, const range_options& options, range_output output)
|
|
222
|
+
{
|
|
223
|
+
Napi::Array result = Napi::Array::New(env);
|
|
224
|
+
auto conv = self.get_convmou();
|
|
225
|
+
scan_range(self, txn, options, [&](const keymou& key, const valuemou& value, std::size_t index) {
|
|
226
|
+
switch (output) {
|
|
227
|
+
case range_output::items:
|
|
228
|
+
result.Set(index, conv.make_result(env, key, value));
|
|
229
|
+
break;
|
|
230
|
+
case range_output::keys:
|
|
231
|
+
result.Set(index, conv.convert_key(env, key));
|
|
232
|
+
break;
|
|
233
|
+
case range_output::values:
|
|
234
|
+
result.Set(index, conv.convert_value(env, value));
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
});
|
|
228
239
|
return result;
|
|
229
240
|
}
|
|
230
241
|
|
|
242
|
+
std::size_t count_range(dbimou& self, txnmou& txn, range_options options)
|
|
243
|
+
{
|
|
244
|
+
options.offset = 0;
|
|
245
|
+
options.limit = std::numeric_limits<std::size_t>::max();
|
|
246
|
+
return scan_range(self, txn, options, [](const keymou&, const valuemou&, std::size_t) {
|
|
247
|
+
return false;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
231
251
|
Napi::Value run_range_query(const Napi::CallbackInfo& info, dbimou& self, const char* method_name, range_output output)
|
|
232
252
|
{
|
|
233
253
|
Napi::Env env = info.Env();
|
|
@@ -247,6 +267,26 @@ Napi::Value run_range_query(const Napi::CallbackInfo& info, dbimou& self, const
|
|
|
247
267
|
}
|
|
248
268
|
}
|
|
249
269
|
|
|
270
|
+
Napi::Value run_range_count(const Napi::CallbackInfo& info, dbimou& self, const char* method_name)
|
|
271
|
+
{
|
|
272
|
+
Napi::Env env = info.Env();
|
|
273
|
+
if (info.Length() < 1) {
|
|
274
|
+
throw Napi::TypeError::New(env, std::string(method_name) + ": txnmou required");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
auto txn = txnmou::unwrap_checked(env, info[0], method_name);
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
auto options = info.Length() > 1 ?
|
|
281
|
+
parse_range_options(env, info[1], self) :
|
|
282
|
+
range_options{};
|
|
283
|
+
auto count = count_range(self, *txn, options);
|
|
284
|
+
return Napi::Number::New(env, static_cast<double>(count));
|
|
285
|
+
} catch (const std::exception& e) {
|
|
286
|
+
throw Napi::Error::New(env, std::string(method_name) + ": " + e.what());
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
250
290
|
} // namespace
|
|
251
291
|
|
|
252
292
|
Napi::FunctionReference dbimou::ctor{};
|
|
@@ -263,6 +303,7 @@ void dbimou::init(const char *class_name, Napi::Env env)
|
|
|
263
303
|
InstanceMethod("keys", &dbimou::keys),
|
|
264
304
|
InstanceMethod("keysFrom", &dbimou::keys_from),
|
|
265
305
|
InstanceMethod("getRange", &dbimou::get_range),
|
|
306
|
+
InstanceMethod("getCount", &dbimou::get_count),
|
|
266
307
|
InstanceMethod("keysRange", &dbimou::keys_range),
|
|
267
308
|
InstanceMethod("valuesRange", &dbimou::values_range),
|
|
268
309
|
InstanceMethod("drop", &dbimou::drop),
|
|
@@ -294,8 +335,15 @@ Napi::Value dbimou::put(const Napi::CallbackInfo& info)
|
|
|
294
335
|
keymou::from(info[1], env, t) :
|
|
295
336
|
keymou::from(info[1], env, key_buf_);
|
|
296
337
|
|
|
297
|
-
auto val = valuemou::from(info[2], env, val_buf_);
|
|
298
|
-
|
|
338
|
+
auto val = valuemou::from(info[2], env, val_buf_, val_num_, is_ordinal(value_mode_));
|
|
339
|
+
MDBX_put_flags_t flags = MDBX_UPSERT;
|
|
340
|
+
if (arg_len > 3 && !info[3].IsUndefined() && !info[3].IsNull()) {
|
|
341
|
+
if (!info[3].IsNumber()) {
|
|
342
|
+
throw Napi::TypeError::New(env, "put: flags must be a number");
|
|
343
|
+
}
|
|
344
|
+
flags = put_flag::parse(info[3]);
|
|
345
|
+
}
|
|
346
|
+
dbi::put(*txn, key, val, flags);
|
|
299
347
|
} catch (const std::exception& e) {
|
|
300
348
|
throw Napi::Error::New(env, std::string("put: ") + e.what());
|
|
301
349
|
}
|
|
@@ -709,6 +757,11 @@ Napi::Value dbimou::get_range(const Napi::CallbackInfo& info)
|
|
|
709
757
|
return run_range_query(info, *this, "getRange", range_output::items);
|
|
710
758
|
}
|
|
711
759
|
|
|
760
|
+
Napi::Value dbimou::get_count(const Napi::CallbackInfo& info)
|
|
761
|
+
{
|
|
762
|
+
return run_range_count(info, *this, "getCount");
|
|
763
|
+
}
|
|
764
|
+
|
|
712
765
|
Napi::Value dbimou::keys_range(const Napi::CallbackInfo& info)
|
|
713
766
|
{
|
|
714
767
|
return run_range_query(info, *this, "keysRange", range_output::keys);
|
package/src/dbimou.hpp
CHANGED
|
@@ -25,6 +25,7 @@ class dbimou final
|
|
|
25
25
|
|
|
26
26
|
buffer_type key_buf_{};
|
|
27
27
|
buffer_type val_buf_{};
|
|
28
|
+
std::uint64_t val_num_{};
|
|
28
29
|
|
|
29
30
|
public:
|
|
30
31
|
static Napi::FunctionReference ctor;
|
|
@@ -73,6 +74,7 @@ public:
|
|
|
73
74
|
Napi::Value keys(const Napi::CallbackInfo&);
|
|
74
75
|
Napi::Value keys_from(const Napi::CallbackInfo&);
|
|
75
76
|
Napi::Value get_range(const Napi::CallbackInfo&);
|
|
77
|
+
Napi::Value get_count(const Napi::CallbackInfo&);
|
|
76
78
|
Napi::Value keys_range(const Napi::CallbackInfo&);
|
|
77
79
|
Napi::Value values_range(const Napi::CallbackInfo&);
|
|
78
80
|
Napi::Value drop(const Napi::CallbackInfo&);
|
|
@@ -124,7 +126,7 @@ public:
|
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
convmou get_convmou() const noexcept {
|
|
127
|
-
return
|
|
129
|
+
return convmou::for_dbi(*this);
|
|
128
130
|
}
|
|
129
131
|
};
|
|
130
132
|
|
package/src/modulemou.cpp
CHANGED
|
@@ -80,6 +80,8 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
|
80
80
|
|
|
81
81
|
Napi::Object value_flag = Napi::Object::New(env);
|
|
82
82
|
MDBXMOU_DECLARE_FLAG_NAME(value_flag, "string", base_flag::string);
|
|
83
|
+
MDBXMOU_DECLARE_FLAG_NAME(value_flag, "number", base_flag::number);
|
|
84
|
+
MDBXMOU_DECLARE_FLAG_NAME(value_flag, "bigint", base_flag::bigint);
|
|
83
85
|
mdbx_mou.Set("valueFlag", value_flag);
|
|
84
86
|
|
|
85
87
|
using mdbxmou::db_mode;
|
|
@@ -97,6 +99,18 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
|
97
99
|
MDBXMOU_DECLARE_FLAG_NAME(queryMode, "del", query_mode::del);
|
|
98
100
|
mdbx_mou.Set("queryMode", queryMode);
|
|
99
101
|
|
|
102
|
+
using mdbxmou::put_flag;
|
|
103
|
+
Napi::Object putFlag = Napi::Object::New(env);
|
|
104
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "noOverwrite", put_flag::no_overwrite);
|
|
105
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "noDupData", put_flag::no_dup_data);
|
|
106
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "current", put_flag::current);
|
|
107
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "allDups", put_flag::all_dups);
|
|
108
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "reserve", put_flag::reserve);
|
|
109
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "append", put_flag::append);
|
|
110
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "appendDup", put_flag::append_dup);
|
|
111
|
+
MDBXMOU_DECLARE_FLAG_NAME(putFlag, "multiple", put_flag::multiple);
|
|
112
|
+
mdbx_mou.Set("putFlag", putFlag);
|
|
113
|
+
|
|
100
114
|
using move_operation = mdbx::cursor::move_operation;
|
|
101
115
|
Napi::Object cursor_mode = Napi::Object::New(env);
|
|
102
116
|
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "first", move_operation::first);
|
package/src/querymou.cpp
CHANGED
|
@@ -23,20 +23,11 @@ dbimou* async_common::parse(const Napi::Object& arg0)
|
|
|
23
23
|
|
|
24
24
|
void async_key::parse(const async_common& common, const Napi::Value& item)
|
|
25
25
|
{
|
|
26
|
-
// утснавлиаем общие параметры
|
|
27
|
-
auto key_flag = common.key_flag;
|
|
28
|
-
|
|
29
26
|
keymou key{};
|
|
30
27
|
if (mdbx::is_ordinal(common.key_mod)) {
|
|
31
|
-
|
|
32
|
-
key = keymou{item.As<Napi::BigInt>(), id_buf};
|
|
33
|
-
} else if (item.IsNumber()) {
|
|
34
|
-
key = keymou{item.As<Napi::Number>(), id_buf};
|
|
35
|
-
}
|
|
28
|
+
key = keymou::from(item, item.Env(), id_buf);
|
|
36
29
|
} else {
|
|
37
|
-
key = (
|
|
38
|
-
keymou{item.As<Napi::String>(), item.Env(), key_buf} :
|
|
39
|
-
keymou{item.As<Napi::Buffer<char>>(), key_buf};
|
|
30
|
+
key = keymou::from(item, item.Env(), key_buf);
|
|
40
31
|
}
|
|
41
32
|
}
|
|
42
33
|
|
|
@@ -44,12 +35,14 @@ void async_keyval::parse(const query_line& common, const Napi::Object& item)
|
|
|
44
35
|
{
|
|
45
36
|
async_key::parse(common, item);
|
|
46
37
|
// проверяем надо ли что-то писать
|
|
47
|
-
if (common.mode.
|
|
38
|
+
if (common.mode.is_write()) {
|
|
48
39
|
valuemou val{};
|
|
49
40
|
auto item_val = item.Get("value");
|
|
50
|
-
val = (common.
|
|
51
|
-
valuemou
|
|
52
|
-
|
|
41
|
+
val = is_ordinal(common.val_mod) ?
|
|
42
|
+
valuemou::from(item_val, item_val.Env(), val_num) :
|
|
43
|
+
(common.value_flag & base_flag::string) ?
|
|
44
|
+
valuemou{item_val.As<Napi::String>(), item_val.Env(), val_buf} :
|
|
45
|
+
valuemou{item_val.As<Napi::Buffer<char>>(), val_buf};
|
|
53
46
|
}
|
|
54
47
|
}
|
|
55
48
|
|
|
@@ -63,6 +56,13 @@ void query_line::parse(txn_mode txn, const Napi::Object& arg0)
|
|
|
63
56
|
} else if (arg0.Has("queryMode")) {
|
|
64
57
|
mode = query_mode::parse(txn, arg0.Get("queryMode").As<Napi::Number>());
|
|
65
58
|
}
|
|
59
|
+
if (arg0.Has("putFlag")) {
|
|
60
|
+
put_flags = put_flag::parse_query(arg0.Get("putFlag"));
|
|
61
|
+
if (!mode.is_write()) {
|
|
62
|
+
throw Napi::TypeError::New(arg0.Env(),
|
|
63
|
+
"query putFlag requires write queryMode");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
66
|
auto items_array = arg0.Get("item").As<Napi::Array>();
|
|
67
67
|
auto item_len = items_array.Length();
|
|
68
68
|
if (item_len > 0) {
|
package/src/querymou.hpp
CHANGED
|
@@ -39,6 +39,7 @@ struct async_keyval
|
|
|
39
39
|
: async_key
|
|
40
40
|
{
|
|
41
41
|
buffer_type val_buf{};
|
|
42
|
+
std::uint64_t val_num{};
|
|
42
43
|
bool found{false};
|
|
43
44
|
|
|
44
45
|
void parse(const query_line& line, const Napi::Object& obj);
|
|
@@ -57,6 +58,7 @@ struct query_line
|
|
|
57
58
|
{
|
|
58
59
|
base_flag value_flag{};
|
|
59
60
|
query_mode mode{};
|
|
61
|
+
put_flag put_flags{};
|
|
60
62
|
// буффер для запроса / ответа
|
|
61
63
|
std::vector<async_keyval> item{};
|
|
62
64
|
void parse(txn_mode txn, const Napi::Object& arg0);
|
|
@@ -83,4 +85,4 @@ struct keys_line
|
|
|
83
85
|
using keys_request = std::vector<keys_line>;
|
|
84
86
|
keys_request parse_keys(const Napi::Value& obj);
|
|
85
87
|
|
|
86
|
-
} // namespace mdbxmou
|
|
88
|
+
} // namespace mdbxmou
|
package/src/txnmou.cpp
CHANGED
|
@@ -159,7 +159,7 @@ Napi::Value txnmou::get_dbi(const Napi::Object& arg0, db_mode db_mode)
|
|
|
159
159
|
if (arg0.Has("valueMode")) {
|
|
160
160
|
auto value = arg0.Get("valueMode");
|
|
161
161
|
if (!value.IsUndefined() && !value.IsNull()) {
|
|
162
|
-
value_mode =
|
|
162
|
+
value_mode = parse_value_mode(value, value_flag);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -189,7 +189,7 @@ Napi::Value txnmou::get_dbi(const Napi::CallbackInfo& info, db_mode db_mode)
|
|
|
189
189
|
auto arg2 = info[2]; // value_mode
|
|
190
190
|
db_name = arg0.As<Napi::String>().Utf8Value();
|
|
191
191
|
key_mode = parse_key_mode(env, arg1, key_flag);
|
|
192
|
-
value_mode =
|
|
192
|
+
value_mode = parse_value_mode(arg2, value_flag);
|
|
193
193
|
} else if (arg_count == 2) {
|
|
194
194
|
// db_name + key_mode || key_mode + value_mode
|
|
195
195
|
auto arg0 = info[0];
|
|
@@ -199,7 +199,7 @@ Napi::Value txnmou::get_dbi(const Napi::CallbackInfo& info, db_mode db_mode)
|
|
|
199
199
|
key_mode = parse_key_mode(env, arg1, key_flag);
|
|
200
200
|
} else {
|
|
201
201
|
key_mode = parse_key_mode(env, arg0, key_flag);
|
|
202
|
-
value_mode =
|
|
202
|
+
value_mode = parse_value_mode(arg1, value_flag);
|
|
203
203
|
}
|
|
204
204
|
} else if (arg_count == 1) {
|
|
205
205
|
// db_name || key_mode
|