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.
- package/.github/workflows/ci.yml +32 -0
- package/.github/workflows/publish.yml +27 -0
- package/.gitmodules +3 -0
- package/CMakeLists.txt +53 -0
- package/LICENSE +201 -0
- package/README.md +639 -0
- package/build.js +11 -0
- package/deps/libmdbx/.clang-format +3 -0
- package/deps/libmdbx/.cmake-format.yaml +3 -0
- package/deps/libmdbx/.le.ini +40 -0
- package/deps/libmdbx/CMakeLists.txt +1269 -0
- package/deps/libmdbx/COPYRIGHT +159 -0
- package/deps/libmdbx/ChangeLog.md +2786 -0
- package/deps/libmdbx/GNUmakefile +950 -0
- package/deps/libmdbx/LICENSE +177 -0
- package/deps/libmdbx/Makefile +16 -0
- package/deps/libmdbx/NOTICE +39 -0
- package/deps/libmdbx/README.md +863 -0
- package/deps/libmdbx/TODO.md +43 -0
- package/deps/libmdbx/cmake/compiler.cmake +1221 -0
- package/deps/libmdbx/cmake/profile.cmake +58 -0
- package/deps/libmdbx/cmake/utils.cmake +524 -0
- package/deps/libmdbx/conanfile.py +323 -0
- package/deps/libmdbx/docs/Doxyfile.in +2734 -0
- package/deps/libmdbx/docs/_preface.md +47 -0
- package/deps/libmdbx/docs/_restrictions.md +248 -0
- package/deps/libmdbx/docs/_starting.md +245 -0
- package/deps/libmdbx/docs/_toc.md +34 -0
- package/deps/libmdbx/docs/header.html +96 -0
- package/deps/libmdbx/example/CMakeLists.txt +6 -0
- package/deps/libmdbx/example/README.md +1 -0
- package/deps/libmdbx/example/example-mdbx.c +154 -0
- package/deps/libmdbx/example/sample-bdb.txt +77 -0
- package/deps/libmdbx/mdbx.h +6655 -0
- package/deps/libmdbx/mdbx.h++ +6428 -0
- package/deps/libmdbx/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +173 -0
- package/deps/libmdbx/src/alloy.c +54 -0
- package/deps/libmdbx/src/api-cold.c +543 -0
- package/deps/libmdbx/src/api-copy.c +912 -0
- package/deps/libmdbx/src/api-cursor.c +754 -0
- package/deps/libmdbx/src/api-dbi.c +315 -0
- package/deps/libmdbx/src/api-env.c +1434 -0
- package/deps/libmdbx/src/api-extra.c +165 -0
- package/deps/libmdbx/src/api-key-transform.c +197 -0
- package/deps/libmdbx/src/api-misc.c +286 -0
- package/deps/libmdbx/src/api-opts.c +575 -0
- package/deps/libmdbx/src/api-range-estimate.c +365 -0
- package/deps/libmdbx/src/api-txn-data.c +454 -0
- package/deps/libmdbx/src/api-txn.c +921 -0
- package/deps/libmdbx/src/atomics-ops.h +364 -0
- package/deps/libmdbx/src/atomics-types.h +97 -0
- package/deps/libmdbx/src/audit.c +109 -0
- package/deps/libmdbx/src/bits.md +34 -0
- package/deps/libmdbx/src/chk.c +1796 -0
- package/deps/libmdbx/src/cogs.c +309 -0
- package/deps/libmdbx/src/cogs.h +506 -0
- package/deps/libmdbx/src/coherency.c +170 -0
- package/deps/libmdbx/src/config.h.in +88 -0
- package/deps/libmdbx/src/cursor.c +2396 -0
- package/deps/libmdbx/src/cursor.h +391 -0
- package/deps/libmdbx/src/dbi.c +717 -0
- package/deps/libmdbx/src/dbi.h +142 -0
- package/deps/libmdbx/src/debug_begin.h +36 -0
- package/deps/libmdbx/src/debug_end.h +15 -0
- package/deps/libmdbx/src/dpl.c +486 -0
- package/deps/libmdbx/src/dpl.h +134 -0
- package/deps/libmdbx/src/dxb.c +1335 -0
- package/deps/libmdbx/src/env.c +607 -0
- package/deps/libmdbx/src/essentials.h +125 -0
- package/deps/libmdbx/src/gc-get.c +1345 -0
- package/deps/libmdbx/src/gc-put.c +970 -0
- package/deps/libmdbx/src/gc.h +40 -0
- package/deps/libmdbx/src/global.c +474 -0
- package/deps/libmdbx/src/internals.h +585 -0
- package/deps/libmdbx/src/layout-dxb.h +288 -0
- package/deps/libmdbx/src/layout-lck.h +289 -0
- package/deps/libmdbx/src/lck-posix.c +859 -0
- package/deps/libmdbx/src/lck-windows.c +607 -0
- package/deps/libmdbx/src/lck.c +174 -0
- package/deps/libmdbx/src/lck.h +110 -0
- package/deps/libmdbx/src/logging_and_debug.c +250 -0
- package/deps/libmdbx/src/logging_and_debug.h +159 -0
- package/deps/libmdbx/src/man1/mdbx_chk.1 +106 -0
- package/deps/libmdbx/src/man1/mdbx_copy.1 +95 -0
- package/deps/libmdbx/src/man1/mdbx_drop.1 +48 -0
- package/deps/libmdbx/src/man1/mdbx_dump.1 +101 -0
- package/deps/libmdbx/src/man1/mdbx_load.1 +105 -0
- package/deps/libmdbx/src/man1/mdbx_stat.1 +86 -0
- package/deps/libmdbx/src/mdbx.c++ +1837 -0
- package/deps/libmdbx/src/meta.c +656 -0
- package/deps/libmdbx/src/meta.h +168 -0
- package/deps/libmdbx/src/mvcc-readers.c +414 -0
- package/deps/libmdbx/src/node.c +365 -0
- package/deps/libmdbx/src/node.h +102 -0
- package/deps/libmdbx/src/ntdll.def +1246 -0
- package/deps/libmdbx/src/options.h +534 -0
- package/deps/libmdbx/src/osal.c +3485 -0
- package/deps/libmdbx/src/osal.h +587 -0
- package/deps/libmdbx/src/page-get.c +483 -0
- package/deps/libmdbx/src/page-iov.c +185 -0
- package/deps/libmdbx/src/page-iov.h +34 -0
- package/deps/libmdbx/src/page-ops.c +744 -0
- package/deps/libmdbx/src/page-ops.h +142 -0
- package/deps/libmdbx/src/pnl.c +236 -0
- package/deps/libmdbx/src/pnl.h +146 -0
- package/deps/libmdbx/src/preface.h +990 -0
- package/deps/libmdbx/src/proto.h +105 -0
- package/deps/libmdbx/src/refund.c +212 -0
- package/deps/libmdbx/src/sort.h +484 -0
- package/deps/libmdbx/src/spill.c +431 -0
- package/deps/libmdbx/src/spill.h +74 -0
- package/deps/libmdbx/src/table.c +107 -0
- package/deps/libmdbx/src/tls.c +551 -0
- package/deps/libmdbx/src/tls.h +43 -0
- package/deps/libmdbx/src/tools/chk.c +673 -0
- package/deps/libmdbx/src/tools/copy.c +166 -0
- package/deps/libmdbx/src/tools/drop.c +199 -0
- package/deps/libmdbx/src/tools/dump.c +515 -0
- package/deps/libmdbx/src/tools/load.c +831 -0
- package/deps/libmdbx/src/tools/stat.c +516 -0
- package/deps/libmdbx/src/tools/wingetopt.c +87 -0
- package/deps/libmdbx/src/tools/wingetopt.h +30 -0
- package/deps/libmdbx/src/tree-ops.c +1554 -0
- package/deps/libmdbx/src/tree-search.c +140 -0
- package/deps/libmdbx/src/txl.c +99 -0
- package/deps/libmdbx/src/txl.h +26 -0
- package/deps/libmdbx/src/txn.c +1083 -0
- package/deps/libmdbx/src/unaligned.h +205 -0
- package/deps/libmdbx/src/utils.c +32 -0
- package/deps/libmdbx/src/utils.h +76 -0
- package/deps/libmdbx/src/version.c.in +44 -0
- package/deps/libmdbx/src/walk.c +290 -0
- package/deps/libmdbx/src/walk.h +20 -0
- package/deps/libmdbx/src/windows-import.c +152 -0
- package/deps/libmdbx/src/windows-import.h +128 -0
- package/deps/libmdbx/test/CMakeLists.txt +317 -0
- package/deps/libmdbx/test/append.c++ +237 -0
- package/deps/libmdbx/test/base.h++ +92 -0
- package/deps/libmdbx/test/battery-tmux.sh +64 -0
- package/deps/libmdbx/test/cases.c++ +118 -0
- package/deps/libmdbx/test/chrono.c++ +134 -0
- package/deps/libmdbx/test/chrono.h++ +85 -0
- package/deps/libmdbx/test/config.c++ +643 -0
- package/deps/libmdbx/test/config.h++ +334 -0
- package/deps/libmdbx/test/copy.c++ +62 -0
- package/deps/libmdbx/test/dead.c++ +39 -0
- package/deps/libmdbx/test/dump-load.sh +40 -0
- package/deps/libmdbx/test/extra/crunched_delete.c++ +409 -0
- package/deps/libmdbx/test/extra/cursor_closing.c++ +410 -0
- package/deps/libmdbx/test/extra/dbi.c++ +229 -0
- package/deps/libmdbx/test/extra/doubtless_positioning.c++ +253 -0
- package/deps/libmdbx/test/extra/dupfix_addodd.c +94 -0
- package/deps/libmdbx/test/extra/dupfix_multiple.c++ +311 -0
- package/deps/libmdbx/test/extra/early_close_dbi.c++ +137 -0
- package/deps/libmdbx/test/extra/hex_base64_base58.c++ +118 -0
- package/deps/libmdbx/test/extra/maindb_ordinal.c++ +61 -0
- package/deps/libmdbx/test/extra/open.c++ +96 -0
- package/deps/libmdbx/test/extra/pcrf/README.md +2 -0
- package/deps/libmdbx/test/extra/pcrf/pcrf_test.c +380 -0
- package/deps/libmdbx/test/extra/probe.c++ +10 -0
- package/deps/libmdbx/test/extra/txn.c++ +407 -0
- package/deps/libmdbx/test/extra/upsert_alldups.c +193 -0
- package/deps/libmdbx/test/fork.c++ +263 -0
- package/deps/libmdbx/test/hill.c++ +447 -0
- package/deps/libmdbx/test/jitter.c++ +197 -0
- package/deps/libmdbx/test/keygen.c++ +393 -0
- package/deps/libmdbx/test/keygen.h++ +130 -0
- package/deps/libmdbx/test/log.c++ +358 -0
- package/deps/libmdbx/test/log.h++ +91 -0
- package/deps/libmdbx/test/main.c++ +706 -0
- package/deps/libmdbx/test/nested.c++ +318 -0
- package/deps/libmdbx/test/osal-unix.c++ +647 -0
- package/deps/libmdbx/test/osal-windows.c++ +440 -0
- package/deps/libmdbx/test/osal.h++ +41 -0
- package/deps/libmdbx/test/stochastic.sh +690 -0
- package/deps/libmdbx/test/stub/LICENSE +24 -0
- package/deps/libmdbx/test/stub/README.md +8 -0
- package/deps/libmdbx/test/stub/pthread_barrier.c +104 -0
- package/deps/libmdbx/test/stub/pthread_barrier.h +77 -0
- package/deps/libmdbx/test/test.c++ +1551 -0
- package/deps/libmdbx/test/test.h++ +298 -0
- package/deps/libmdbx/test/tmux.conf +3 -0
- package/deps/libmdbx/test/try.c++ +30 -0
- package/deps/libmdbx/test/ttl.c++ +240 -0
- package/deps/libmdbx/test/utils.c++ +203 -0
- package/deps/libmdbx/test/utils.h++ +326 -0
- package/deps/libmdbx/test/valgrind_suppress.txt +536 -0
- package/lib/mdbx_evn_async.js +211 -0
- package/lib/mdbx_worker.js +195 -0
- package/lib/nativemou.js +6 -0
- package/package.json +38 -0
- package/src/async/envmou_close.cpp +34 -0
- package/src/async/envmou_close.hpp +32 -0
- package/src/async/envmou_copy_to.cpp +29 -0
- package/src/async/envmou_copy_to.hpp +38 -0
- package/src/async/envmou_keys.cpp +201 -0
- package/src/async/envmou_keys.hpp +50 -0
- package/src/async/envmou_open.cpp +38 -0
- package/src/async/envmou_open.hpp +33 -0
- package/src/async/envmou_query.cpp +167 -0
- package/src/async/envmou_query.hpp +53 -0
- package/src/dbimou.cpp +522 -0
- package/src/dbimou.hpp +82 -0
- package/src/env_arg0.hpp +24 -0
- package/src/envmou.cpp +445 -0
- package/src/envmou.hpp +116 -0
- package/src/modulemou.cpp +113 -0
- package/src/querymou.cpp +177 -0
- package/src/querymou.hpp +93 -0
- package/src/txnmou.cpp +254 -0
- package/src/txnmou.hpp +122 -0
- package/src/typemou.hpp +239 -0
- package/src/valuemou.hpp +194 -0
- package/test/async.js +67 -0
- package/test/e3.js +38 -0
- package/test/e4.js +89 -0
- package/test/e5.js +162 -0
- package/test/test-batch-ops.js +243 -0
- package/test/test-cursor-mode.js +84 -0
- package/test/test-multi-mode.js +87 -0
package/README.md
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
# mdbxmou
|
|
2
|
+
|
|
3
|
+
High-performance Node.js binding for libmdbx — a fast, lightweight, embedded key-value database.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Synchronous API** — Direct MDBX operations in main thread
|
|
8
|
+
- **Asynchronous API** — Background operations via single Worker Thread
|
|
9
|
+
- **Transactions** — ACID transactions with read/write modes
|
|
10
|
+
- **Multiple key/value types** — String, binary, ordinal (integer) keys
|
|
11
|
+
- **Batch operations** — Efficient multi-key read/write
|
|
12
|
+
- **Memory-mapped** — Zero-copy data access
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install mdbxmou
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
24
|
+
|
|
25
|
+
// Create environment
|
|
26
|
+
const env = new MDBX_Env();
|
|
27
|
+
await env.open({
|
|
28
|
+
path: './data',
|
|
29
|
+
keyFlag: MDBX_Param.keyFlag.string, // Default key encoding (optional)
|
|
30
|
+
valueFlag: MDBX_Param.valueFlag.string // Default value encoding (optional)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Write data
|
|
34
|
+
const txn = env.startWrite();
|
|
35
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
36
|
+
dbi.put(1, "hello");
|
|
37
|
+
dbi.put(2, "world");
|
|
38
|
+
txn.commit();
|
|
39
|
+
|
|
40
|
+
// Read data
|
|
41
|
+
const readTxn = env.startRead();
|
|
42
|
+
const readDbi = readTxn.openMap(BigInt(MDBX_Param.keyMode.ordinal));
|
|
43
|
+
const value = readDbi.get(1);
|
|
44
|
+
console.log(value); // "hello"
|
|
45
|
+
readTxn.commit();
|
|
46
|
+
|
|
47
|
+
await env.close();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API Reference
|
|
51
|
+
|
|
52
|
+
### Environment (MDBX_Env)
|
|
53
|
+
|
|
54
|
+
#### Constructor
|
|
55
|
+
```javascript
|
|
56
|
+
const env = new MDBX_Env();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Methods
|
|
60
|
+
|
|
61
|
+
**open(options) → Promise**
|
|
62
|
+
```javascript
|
|
63
|
+
await env.open({
|
|
64
|
+
path: './database', // Database directory
|
|
65
|
+
keyFlag: MDBX_Param.keyFlag.string, // Default key encoding (optional)
|
|
66
|
+
valueFlag: MDBX_Param.valueFlag.string, // Default value encoding (optional)
|
|
67
|
+
envFlag: MDBX_Param.envFlag.nostickythreads
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Options:
|
|
72
|
+
- `path` - Database directory path
|
|
73
|
+
- `keyFlag` - Default key encoding for all operations (optional, defaults to Buffer)
|
|
74
|
+
- Only `string` can be set (ordinal mode uses `number`/`bigint` separately)
|
|
75
|
+
- `valueFlag` - Default value encoding for all operations (optional, defaults to Buffer)
|
|
76
|
+
- `envFlag` - Environment flags
|
|
77
|
+
- `mapSize` - Maximum database size
|
|
78
|
+
- `maxReaders` - Maximum number of readers
|
|
79
|
+
- `maxDbs` - Maximum number of databases
|
|
80
|
+
|
|
81
|
+
Note: When `keyFlag` or `valueFlag` are set at environment level, they become defaults for all subsequent operations unless explicitly overridden.
|
|
82
|
+
|
|
83
|
+
**close() → Promise**
|
|
84
|
+
```javascript
|
|
85
|
+
await env.close();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**openSync(options)**
|
|
89
|
+
```javascript
|
|
90
|
+
env.openSync({
|
|
91
|
+
path: './database',
|
|
92
|
+
valueFlag: MDBX_Param.valueFlag.string
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**closeSync()**
|
|
97
|
+
```javascript
|
|
98
|
+
env.closeSync();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**startWrite() → Transaction**
|
|
102
|
+
```javascript
|
|
103
|
+
const txn = env.startWrite();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**startRead() → Transaction**
|
|
107
|
+
```javascript
|
|
108
|
+
const txn = env.startRead();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**query(requests) → Promise<Array>** (Async batch operations)
|
|
112
|
+
```javascript
|
|
113
|
+
const result = await env.query([
|
|
114
|
+
{
|
|
115
|
+
dbMode: MDBX_Param.dbMode.accede,
|
|
116
|
+
keyMode: MDBX_Param.keyMode.ordinal,
|
|
117
|
+
mode: MDBX_Param.queryMode.get,
|
|
118
|
+
item: [{ key: 1 }, { key: 2 }]
|
|
119
|
+
}
|
|
120
|
+
]);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Transaction
|
|
124
|
+
|
|
125
|
+
#### Methods
|
|
126
|
+
|
|
127
|
+
**createMap(keyMode, [valueMode], [flags], [name]) → DBI**
|
|
128
|
+
```javascript
|
|
129
|
+
// No arguments - default keyMode (0) and valueMode (0)
|
|
130
|
+
const dbi = txn.createMap();
|
|
131
|
+
|
|
132
|
+
// One argument - keyMode only
|
|
133
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
134
|
+
|
|
135
|
+
// Two arguments - keyMode + valueMode
|
|
136
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal, MDBX_Param.valueMode.multi);
|
|
137
|
+
|
|
138
|
+
// Two arguments - db_name + keyMode
|
|
139
|
+
const namedDbi = txn.createMap("my-table", MDBX_Param.keyMode.ordinal);
|
|
140
|
+
|
|
141
|
+
// Three arguments - db_name + keyMode + valueMode
|
|
142
|
+
const namedDbi = txn.createMap("my-table", MDBX_Param.keyMode.ordinal, MDBX_Param.valueMode.multi);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> **Note**: Use `createMap` in write transactions - it will create the database if it doesn't exist, or open it if it does. This is safer for new environments.
|
|
146
|
+
|
|
147
|
+
**openMap(keyMode, [name]) → DBI**
|
|
148
|
+
```javascript
|
|
149
|
+
// No arguments - default keyMode (0)
|
|
150
|
+
const dbi = txn.openMap();
|
|
151
|
+
|
|
152
|
+
// One argument - keyMode only
|
|
153
|
+
// Number keyMode - keys returned as numbers
|
|
154
|
+
const dbi = txn.openMap(MDBX_Param.keyMode.ordinal);
|
|
155
|
+
// BigInt keyMode - keys returned as BigInts
|
|
156
|
+
const dbi = txn.openMap(BigInt(MDBX_Param.keyMode.ordinal));
|
|
157
|
+
|
|
158
|
+
// Two arguments - db_name + keyMode
|
|
159
|
+
const namedDbi = txn.openMap("my-table", MDBX_Param.keyMode.ordinal);
|
|
160
|
+
const namedDbiBigInt = txn.openMap("my-table", BigInt(MDBX_Param.keyMode.ordinal));
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> **Note**: Use `openMap` in read transactions or when you're sure the database already exists. For write transactions on new environments, prefer `createMap`.
|
|
164
|
+
|
|
165
|
+
> **Note**: When using ordinal keyMode, the key type in results depends on how you specify keyMode:
|
|
166
|
+
> - `keyMode: number` → keys returned as `number`
|
|
167
|
+
> - `keyMode: BigInt(number)` → keys returned as `BigInt`
|
|
168
|
+
|
|
169
|
+
**commit()**
|
|
170
|
+
```javascript
|
|
171
|
+
txn.commit();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**abort()**
|
|
175
|
+
```javascript
|
|
176
|
+
txn.abort();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### DBI (Database Instance)
|
|
180
|
+
|
|
181
|
+
#### Methods
|
|
182
|
+
|
|
183
|
+
**put(key, value, [flags])**
|
|
184
|
+
```javascript
|
|
185
|
+
dbi.put(123, "value");
|
|
186
|
+
dbi.put("key", Buffer.from("binary data"));
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**get(key) → value**
|
|
190
|
+
```javascript
|
|
191
|
+
const value = dbi.get(123);
|
|
192
|
+
const binary = dbi.get("key");
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**del(key) → boolean**
|
|
196
|
+
```javascript
|
|
197
|
+
const deleted = dbi.del(123);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**stat() → Object**
|
|
201
|
+
```javascript
|
|
202
|
+
const stats = dbi.stat();
|
|
203
|
+
// { pageSize: 4096, depth: 1, entries: 10, ... }
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**forEach(callback)**
|
|
207
|
+
```javascript
|
|
208
|
+
dbi.forEach((key, value, index) => {
|
|
209
|
+
console.log(`${key}: ${value}`);
|
|
210
|
+
return false; // continue iteration (or undefined)
|
|
211
|
+
// return true; // stop iteration
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
> **Note**: forEach continues scanning while callback returns `undefined` or `false`, and stops when callback returns `true`.
|
|
216
|
+
|
|
217
|
+
**keys() → Array**
|
|
218
|
+
```javascript
|
|
219
|
+
// Get all keys
|
|
220
|
+
const allKeys = dbi.keys();
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**keysFrom(startKey, [limit], [cursorMode]) → Array**
|
|
224
|
+
```javascript
|
|
225
|
+
// Get keys starting from specific key
|
|
226
|
+
const keys = dbi.keysFrom(42, 50); // 50 keys starting from 42
|
|
227
|
+
|
|
228
|
+
// With cursor mode
|
|
229
|
+
const keys = dbi.keysFrom(42, 50, 'keyGreaterOrEqual');
|
|
230
|
+
|
|
231
|
+
// BigInt keys
|
|
232
|
+
const bigIntKeys = dbi.keysFrom(42n, 50);
|
|
233
|
+
|
|
234
|
+
// Key equal mode (for multi-value databases)
|
|
235
|
+
const equalKeys = dbi.keysFrom(5, 10, 'keyEqual');
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**query(requests) → Promise<Array>** (Async batch operations)
|
|
239
|
+
```javascript
|
|
240
|
+
dbi.forEach((key, value, index) => {
|
|
241
|
+
console.log(`${key}: ${value}`);
|
|
242
|
+
// return false; // continue iteration (or undefined)
|
|
243
|
+
// return true; // stop iteration
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Key and Value Types
|
|
248
|
+
|
|
249
|
+
### Key Modes (MDBX_Param.keyMode)
|
|
250
|
+
|
|
251
|
+
- **Default (0)** - Buffer keys (no flags, default behavior)
|
|
252
|
+
- **reverse** - Keys sorted in reverse order
|
|
253
|
+
- **ordinal** - Integer keys (4 or 8 bytes, native endian)
|
|
254
|
+
|
|
255
|
+
### Value Modes (MDBX_Param.valueMode)
|
|
256
|
+
|
|
257
|
+
- **single** - Single value per key (default)
|
|
258
|
+
- **multi** - Multiple values per key (dupsort)
|
|
259
|
+
|
|
260
|
+
### Value Flags (MDBX_Param.valueFlag)
|
|
261
|
+
|
|
262
|
+
- **binary** - Raw binary data (default)
|
|
263
|
+
- **string** - UTF-8 strings
|
|
264
|
+
|
|
265
|
+
## Examples
|
|
266
|
+
|
|
267
|
+
### Basic Usage (Synchronous)
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
271
|
+
|
|
272
|
+
function syncExample() {
|
|
273
|
+
const env = new MDBX_Env();
|
|
274
|
+
|
|
275
|
+
// Synchronous open
|
|
276
|
+
env.openSync({ path: './data' });
|
|
277
|
+
|
|
278
|
+
// Write transaction
|
|
279
|
+
const writeTxn = env.startWrite();
|
|
280
|
+
const dbi = writeTxn.createMap(MDBX_Param.keyMode.ordinal);
|
|
281
|
+
|
|
282
|
+
for (let i = 0; i < 1000; i++) {
|
|
283
|
+
dbi.put(i, `value_${i}`);
|
|
284
|
+
}
|
|
285
|
+
writeTxn.commit();
|
|
286
|
+
|
|
287
|
+
// Read transaction with number keys
|
|
288
|
+
const readTxn = env.startRead();
|
|
289
|
+
const readDbi = readTxn.openMap(MDBX_Param.keyMode.ordinal); // keys as numbers
|
|
290
|
+
|
|
291
|
+
const value = readDbi.get(42);
|
|
292
|
+
console.log(value); // "value_42"
|
|
293
|
+
|
|
294
|
+
// Iterate with cursor
|
|
295
|
+
readDbi.forEach((key, value, index) => {
|
|
296
|
+
console.log(`Key ${key} (type: ${typeof key}): ${value}`); // key is number
|
|
297
|
+
return index >= 9; // stop after 10 items (indices 0-9)
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// Get specific keys
|
|
301
|
+
const someKeys = readDbi.keysFrom(100, { limit: 50 });
|
|
302
|
+
console.log(`Keys 100-149:`, someKeys); // array of numbers
|
|
303
|
+
|
|
304
|
+
readTxn.commit();
|
|
305
|
+
|
|
306
|
+
// Synchronous close
|
|
307
|
+
env.closeSync();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async function asyncExample() {
|
|
311
|
+
const env = new MDBX_Env();
|
|
312
|
+
await env.open({ path: './data-async' });
|
|
313
|
+
|
|
314
|
+
// Write transaction
|
|
315
|
+
const writeTxn = env.startWrite();
|
|
316
|
+
const dbi = writeTxn.createMap(MDBX_Param.keyMode.ordinal);
|
|
317
|
+
|
|
318
|
+
for (let i = 0; i < 1000; i++) {
|
|
319
|
+
dbi.put(i, `value_${i}`);
|
|
320
|
+
}
|
|
321
|
+
writeTxn.commit();
|
|
322
|
+
|
|
323
|
+
// Read transaction with BigInt keys
|
|
324
|
+
const readTxn = env.startRead();
|
|
325
|
+
const readDbi = readTxn.openMap(BigInt(MDBX_Param.keyMode.ordinal)); // keys as BigInts
|
|
326
|
+
|
|
327
|
+
const value = readDbi.get(42);
|
|
328
|
+
console.log(value); // "value_42"
|
|
329
|
+
|
|
330
|
+
// Iterate with BigInt keys
|
|
331
|
+
readDbi.forEach((key, value, index) => {
|
|
332
|
+
console.log(`Key ${key} (type: ${typeof key}): ${value}`); // key is bigint
|
|
333
|
+
return index >= 9; // stop after 10 items (indices 0-9)
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// Get BigInt keys
|
|
337
|
+
const bigIntKeys = readDbi.keysFrom(100n, { limit: 50 });
|
|
338
|
+
console.log(`Keys 100n-149n:`, bigIntKeys); // array of BigInts
|
|
339
|
+
|
|
340
|
+
readTxn.commit();
|
|
341
|
+
await env.close();
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Key Type Behavior
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
349
|
+
|
|
350
|
+
function keyTypesExample() {
|
|
351
|
+
const env = new MDBX_Env();
|
|
352
|
+
env.openSync({ path: './key-types' });
|
|
353
|
+
|
|
354
|
+
const txn = env.startWrite();
|
|
355
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
356
|
+
|
|
357
|
+
// Store some data
|
|
358
|
+
dbi.put(1, "one");
|
|
359
|
+
dbi.put(2, "two");
|
|
360
|
+
dbi.put(3, "three");
|
|
361
|
+
txn.commit();
|
|
362
|
+
|
|
363
|
+
// Read with number keyMode
|
|
364
|
+
const readTxn1 = env.startRead();
|
|
365
|
+
const numberDbi = readTxn1.openMap(MDBX_Param.keyMode.ordinal);
|
|
366
|
+
|
|
367
|
+
numberDbi.forEach((key, value) => {
|
|
368
|
+
console.log(`Number key: ${key} (${typeof key})`); // number
|
|
369
|
+
// return undefined; // continue iteration (default)
|
|
370
|
+
});
|
|
371
|
+
readTxn1.commit();
|
|
372
|
+
|
|
373
|
+
// Read with BigInt keyMode
|
|
374
|
+
const readTxn2 = env.startRead();
|
|
375
|
+
const bigintDbi = readTxn2.openMap(BigInt(MDBX_Param.keyMode.ordinal));
|
|
376
|
+
|
|
377
|
+
bigintDbi.forEach((key, value) => {
|
|
378
|
+
console.log(`BigInt key: ${key} (${typeof key})`); // bigint
|
|
379
|
+
// return false; // continue iteration
|
|
380
|
+
});
|
|
381
|
+
readTxn2.commit();
|
|
382
|
+
|
|
383
|
+
env.closeSync();
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Cursor Operations
|
|
388
|
+
|
|
389
|
+
```javascript
|
|
390
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
391
|
+
|
|
392
|
+
function cursorExample() {
|
|
393
|
+
const env = new MDBX_Env();
|
|
394
|
+
env.openSync({ path: './cursor-data' });
|
|
395
|
+
|
|
396
|
+
const txn = env.startWrite();
|
|
397
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
398
|
+
|
|
399
|
+
// Store test data
|
|
400
|
+
for (let i = 0; i < 100; i++) {
|
|
401
|
+
dbi.put(i, `value_${i}`);
|
|
402
|
+
}
|
|
403
|
+
txn.commit();
|
|
404
|
+
|
|
405
|
+
const readTxn = env.startRead();
|
|
406
|
+
const readDbi = readTxn.openMap(MDBX_Param.keyMode.ordinal);
|
|
407
|
+
|
|
408
|
+
// Get all keys
|
|
409
|
+
const allKeys = readDbi.keys();
|
|
410
|
+
console.log(`Total keys: ${allKeys.length}`);
|
|
411
|
+
|
|
412
|
+
// Get limited keys - use keysFrom with limit
|
|
413
|
+
const firstTen = readDbi.keysFrom(0, 10);
|
|
414
|
+
console.log(`First 10 keys:`, firstTen);
|
|
415
|
+
|
|
416
|
+
// Get keys from specific position
|
|
417
|
+
const fromFifty = readDbi.keysFrom(50, 20);
|
|
418
|
+
console.log(`Keys 50-69:`, fromFifty);
|
|
419
|
+
|
|
420
|
+
// Reverse iteration - need manual logic or forEach
|
|
421
|
+
const allKeysForReverse = readDbi.keys();
|
|
422
|
+
const lastTen = allKeysForReverse.slice(-10).reverse();
|
|
423
|
+
console.log(`Last 10 keys:`, lastTen);
|
|
424
|
+
|
|
425
|
+
// Manual iteration with forEach
|
|
426
|
+
let count = 0;
|
|
427
|
+
readDbi.forEach((key, value, index) => {
|
|
428
|
+
if (key >= 80) {
|
|
429
|
+
console.log(`Key ${key}: ${value}`);
|
|
430
|
+
count++;
|
|
431
|
+
}
|
|
432
|
+
return count >= 5; // stop after 5 items >= 80
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
readTxn.commit();
|
|
436
|
+
env.closeSync();
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Batch Operations (Asynchronous)
|
|
441
|
+
|
|
442
|
+
```javascript
|
|
443
|
+
const { MDBX_Async_Env } = require('mdbxmou/lib/mdbx_evn_async');
|
|
444
|
+
const { MDBX_Param } = require('mdbxmou');
|
|
445
|
+
|
|
446
|
+
async function batchExample() {
|
|
447
|
+
const env = new MDBX_Async_Env();
|
|
448
|
+
await env.open({ path: './async-data' });
|
|
449
|
+
|
|
450
|
+
// Write transaction in worker thread
|
|
451
|
+
const writeTxn = await env.startWrite();
|
|
452
|
+
const dbi = await writeTxn.openMap({
|
|
453
|
+
keyMode: MDBX_Param.keyMode.ordinal,
|
|
454
|
+
create: true
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Batch write
|
|
458
|
+
await dbi.putBatch([
|
|
459
|
+
{ key: 1n, value: "one" },
|
|
460
|
+
{ key: 2n, value: "two" },
|
|
461
|
+
{ key: 3n, value: "three" }
|
|
462
|
+
]);
|
|
463
|
+
|
|
464
|
+
await writeTxn.commit();
|
|
465
|
+
|
|
466
|
+
// Read transaction in worker thread
|
|
467
|
+
const readTxn = await env.startRead();
|
|
468
|
+
const readDbi = await readTxn.openMap({
|
|
469
|
+
keyMode: MDBX_Param.keyMode.ordinal
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Batch read
|
|
473
|
+
const results = await readDbi.getBatch([1n, 2n, 3n]);
|
|
474
|
+
results.forEach((result, i) => {
|
|
475
|
+
if (result.found) {
|
|
476
|
+
console.log(`Key ${result.key}: ${result.value}`);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
await readTxn.commit();
|
|
481
|
+
await env.close();
|
|
482
|
+
await env.terminate();
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Query API (Advanced Async)
|
|
487
|
+
|
|
488
|
+
```javascript
|
|
489
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
490
|
+
|
|
491
|
+
async function queryExample() {
|
|
492
|
+
const env = new MDBX_Env();
|
|
493
|
+
await env.open({ path: './query-data' });
|
|
494
|
+
|
|
495
|
+
// Async query with multiple databases
|
|
496
|
+
const results = await env.query([
|
|
497
|
+
{
|
|
498
|
+
db: "users",
|
|
499
|
+
dbMode: MDBX_Param.dbMode.create | MDBX_Param.dbMode.accede,
|
|
500
|
+
mode: MDBX_Param.queryMode.put,
|
|
501
|
+
item: [
|
|
502
|
+
{ key: "user1", value: JSON.stringify({ name: "Alice" }) },
|
|
503
|
+
{ key: "user2", value: JSON.stringify({ name: "Bob" }) }
|
|
504
|
+
]
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
db: "users",
|
|
508
|
+
dbMode: MDBX_Param.dbMode.accede,
|
|
509
|
+
mode: MDBX_Param.queryMode.get,
|
|
510
|
+
item: [
|
|
511
|
+
{ key: "user1" },
|
|
512
|
+
{ key: "user2" }
|
|
513
|
+
]
|
|
514
|
+
}
|
|
515
|
+
]);
|
|
516
|
+
|
|
517
|
+
console.log('Query results:', JSON.stringify(results, null, 2));
|
|
518
|
+
await env.close();
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Worker Thread Example
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
const { MDBX_Async_Env } = require('mdbxmou/lib/mdbx_evn_async');
|
|
526
|
+
|
|
527
|
+
async function workerExample() {
|
|
528
|
+
// Single worker thread for all async operations
|
|
529
|
+
const env = new MDBX_Async_Env();
|
|
530
|
+
await env.open({ path: './worker-data' });
|
|
531
|
+
|
|
532
|
+
// Each transaction runs in the same worker thread
|
|
533
|
+
const txn1 = await env.startWrite();
|
|
534
|
+
const dbi1 = await txn1.openMap({
|
|
535
|
+
keyMode: MDBX_Param.keyMode.ordinal,
|
|
536
|
+
create: true
|
|
537
|
+
});
|
|
538
|
+
await dbi1.put(1n, "worker-value-1");
|
|
539
|
+
await txn1.commit();
|
|
540
|
+
|
|
541
|
+
// Another transaction in the same worker
|
|
542
|
+
const txn2 = await env.startWrite();
|
|
543
|
+
const dbi2 = await txn2.openMap({
|
|
544
|
+
keyMode: MDBX_Param.keyMode.ordinal,
|
|
545
|
+
create: true
|
|
546
|
+
});
|
|
547
|
+
await dbi2.put(2n, "worker-value-2");
|
|
548
|
+
await txn2.commit();
|
|
549
|
+
|
|
550
|
+
// Read transaction
|
|
551
|
+
const readTxn = await env.startRead();
|
|
552
|
+
const readDbi = await readTxn.openMap({
|
|
553
|
+
keyMode: MDBX_Param.keyMode.ordinal
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
const results = await readDbi.getBatch([1n, 2n]);
|
|
557
|
+
results.forEach(r => {
|
|
558
|
+
if (r.found) {
|
|
559
|
+
console.log(`Key ${r.key}: ${r.value}`);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
await readTxn.commit();
|
|
564
|
+
|
|
565
|
+
await env.close();
|
|
566
|
+
await env.terminate(); // Terminate the worker thread
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
## Error Handling
|
|
571
|
+
|
|
572
|
+
```javascript
|
|
573
|
+
try {
|
|
574
|
+
const env = new MDBX_Env();
|
|
575
|
+
await env.open({ path: './data' });
|
|
576
|
+
|
|
577
|
+
const txn = env.startWrite();
|
|
578
|
+
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
579
|
+
|
|
580
|
+
// This might throw if key already exists with MDBX_NOOVERWRITE
|
|
581
|
+
dbi.put(123, "value", MDBX_Param.putFlag.nooverwrite);
|
|
582
|
+
|
|
583
|
+
txn.commit();
|
|
584
|
+
} catch (error) {
|
|
585
|
+
console.error('Database error:', error.message);
|
|
586
|
+
if (txn) txn.abort();
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
## Configuration Options
|
|
591
|
+
|
|
592
|
+
### Available Constants (MDBX_Param)
|
|
593
|
+
|
|
594
|
+
```javascript
|
|
595
|
+
const { MDBX_Param } = require('mdbxmou');
|
|
596
|
+
|
|
597
|
+
// Key modes
|
|
598
|
+
MDBX_Param.keyMode.reverse // MDBX_REVERSEKEY - reverse key order
|
|
599
|
+
MDBX_Param.keyMode.ordinal // MDBX_INTEGERKEY - integer keys (use with number/bigint)
|
|
600
|
+
// Default (0) - Buffer keys (no flags)
|
|
601
|
+
|
|
602
|
+
// Key flags (optional, control key representation)
|
|
603
|
+
MDBX_Param.keyFlag.string // UTF-8 string encoding
|
|
604
|
+
MDBX_Param.keyFlag.number // Number type (used with ordinal mode)
|
|
605
|
+
MDBX_Param.keyFlag.bigint // BigInt type (used with ordinal mode)
|
|
606
|
+
// Default - Buffer representation
|
|
607
|
+
|
|
608
|
+
Note: For ordinal (integer) keys, use keyFlag.number or keyFlag.bigint to specify the data type.
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Environment Flags
|
|
612
|
+
- `MDBX_Param.envFlag.nostickythreads` - Don't stick reader transactions to threads
|
|
613
|
+
- `MDBX_Param.envFlag.readonly` - Open database in read-only mode
|
|
614
|
+
|
|
615
|
+
### Database Modes
|
|
616
|
+
- `MDBX_Param.dbMode.create` - Create database if it doesn't exist
|
|
617
|
+
- `MDBX_Param.dbMode.accede` - Open existing database with any flags
|
|
618
|
+
|
|
619
|
+
### Query Modes
|
|
620
|
+
- `MDBX_Param.queryMode.get` - Read operations
|
|
621
|
+
- `MDBX_Param.queryMode.put` - Write operations
|
|
622
|
+
- `MDBX_Param.queryMode.del` - Delete operations
|
|
623
|
+
|
|
624
|
+
## Performance Tips
|
|
625
|
+
|
|
626
|
+
1. **Use ordinal keys** for integer data - much faster than string keys
|
|
627
|
+
2. **Batch operations** - Use query API or async worker thread for bulk operations
|
|
628
|
+
3. **Reuse transactions** - Keep read transactions open for multiple operations
|
|
629
|
+
4. **Worker thread** - Use async API for CPU-intensive or I/O operations
|
|
630
|
+
5. **Memory mapping** - MDBX uses memory-mapped files for zero-copy access
|
|
631
|
+
|
|
632
|
+
## License
|
|
633
|
+
|
|
634
|
+
Apache License 2.0
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
**Documentation generated by GitHub Copilot (Claude 3.5 Sonnet) on August 13, 2025**
|
|
639
|
+
**Reviewed and approved by the library author**
|
package/build.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var spawnSync = require('child_process').spawnSync;
|
|
2
|
+
|
|
3
|
+
function exec(cmd) {
|
|
4
|
+
const { status } = spawnSync(cmd, {
|
|
5
|
+
shell: true,
|
|
6
|
+
stdio: 'inherit',
|
|
7
|
+
});
|
|
8
|
+
process.exit(status);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exec("npx cmake-js rebuild --config Release --CDMDBX_TXN_CHECKOWNER=OFF --CDMDBX_BUILD_CXX=ON --CDMDBX_ENABLE_TESTS=OFF --CDMDBX_BUILD_SHARED_LIBRARY=OFF --CDMDBX_BUILD_TOOLS=OFF --CDMDBX_INSTALL_STATIC=ON");
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
tabsize=8
|
|
2
|
+
indentsize=8
|
|
3
|
+
autoindent=1
|
|
4
|
+
bsunindents=1
|
|
5
|
+
insert=1
|
|
6
|
+
inputmode=0
|
|
7
|
+
editmode=1
|
|
8
|
+
makebak=0
|
|
9
|
+
bakpath=
|
|
10
|
+
make=exec make
|
|
11
|
+
shell=exec $SHELL
|
|
12
|
+
run=exec make run
|
|
13
|
+
compile=exec make "$FNAME.o"
|
|
14
|
+
scroll=1
|
|
15
|
+
hscroll=32
|
|
16
|
+
rblock=0
|
|
17
|
+
savepos=1
|
|
18
|
+
savehst=1
|
|
19
|
+
noreg=1
|
|
20
|
+
match_case=1
|
|
21
|
+
linelen=72
|
|
22
|
+
leftmrg=0
|
|
23
|
+
flnmarg=0
|
|
24
|
+
leftadj=1
|
|
25
|
+
rightadj=0
|
|
26
|
+
helpcmd=exec /usr/share/le/help
|
|
27
|
+
usecolor=1
|
|
28
|
+
usetabs=1
|
|
29
|
+
scrollbar=0
|
|
30
|
+
statusline=0
|
|
31
|
+
backupext=.~%d~
|
|
32
|
+
backupnum=9
|
|
33
|
+
preferpagetop=1
|
|
34
|
+
wordwrap=0
|
|
35
|
+
syntaxhl=1
|
|
36
|
+
undo_enable=1
|
|
37
|
+
undo_min_levels=4
|
|
38
|
+
undo_max_memory=128
|
|
39
|
+
undo_glue=1
|
|
40
|
+
usemouse=0
|