mdbxmou 0.2.1 → 0.2.4
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/CMakeLists.txt +2 -2
- package/README.md +104 -27
- package/build.js +15 -7
- package/lib/async.mjs +7 -0
- package/lib/index.mjs +12 -0
- package/lib/mdbx_worker.js +24 -8
- package/package.json +14 -1
- package/src/async/envmou_keys.cpp +1 -13
- package/src/async/envmou_query.cpp +1 -14
- package/src/dbimou.cpp +2 -4
- package/src/dbimou.hpp +28 -2
- package/src/envmou.cpp +3 -8
- package/src/modulemou.cpp +10 -10
- package/src/querymou.cpp +45 -77
- package/src/querymou.hpp +9 -16
- package/src/txnmou.cpp +0 -8
- package/src/txnmou.hpp +0 -2
- package/src/typemou.hpp +2 -2
package/CMakeLists.txt
CHANGED
|
@@ -23,8 +23,8 @@ add_library(${PROJECT_NAME} SHARED
|
|
|
23
23
|
"src/querymou.cpp"
|
|
24
24
|
"src/envmou.cpp"
|
|
25
25
|
"src/txnmou.cpp"
|
|
26
|
-
"src/
|
|
27
|
-
"src/
|
|
26
|
+
"src/dbimou.cpp"
|
|
27
|
+
"src/dbi.cpp")
|
|
28
28
|
|
|
29
29
|
# Gives our library file a .node extension without any "lib" prefix
|
|
30
30
|
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
|
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ npm install mdbxmou
|
|
|
19
19
|
|
|
20
20
|
## Quick Start
|
|
21
21
|
|
|
22
|
+
CommonJS:
|
|
23
|
+
|
|
22
24
|
```javascript
|
|
23
25
|
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
24
26
|
|
|
@@ -47,6 +49,12 @@ readTxn.commit();
|
|
|
47
49
|
await env.close();
|
|
48
50
|
```
|
|
49
51
|
|
|
52
|
+
ESM:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import { MDBX_Env, MDBX_Param } from "mdbxmou";
|
|
56
|
+
```
|
|
57
|
+
|
|
50
58
|
## API Reference
|
|
51
59
|
|
|
52
60
|
### Environment (MDBX_Env)
|
|
@@ -64,19 +72,19 @@ await env.open({
|
|
|
64
72
|
path: './database', // Database directory
|
|
65
73
|
keyFlag: MDBX_Param.keyFlag.string, // Default key encoding (optional)
|
|
66
74
|
valueFlag: MDBX_Param.valueFlag.string, // Default value encoding (optional)
|
|
67
|
-
|
|
75
|
+
flags: MDBX_Param.envFlag.nostickythreads
|
|
68
76
|
});
|
|
69
77
|
```
|
|
70
78
|
|
|
71
79
|
Options:
|
|
72
80
|
- `path` - Database directory path
|
|
81
|
+
- `flags` - Environment flags (optional, defaults to `0`)
|
|
73
82
|
- `keyFlag` - Default key encoding for all operations (optional, defaults to Buffer)
|
|
74
83
|
- Only `string` can be set (ordinal mode uses `number`/`bigint` separately)
|
|
75
84
|
- `valueFlag` - Default value encoding for all operations (optional, defaults to Buffer)
|
|
76
|
-
- `
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
79
|
-
- `maxDbs` - Maximum number of databases
|
|
85
|
+
- `maxDbi` - Maximum number of databases (optional, default `32`)
|
|
86
|
+
- `mode` - Filesystem permissions mode (optional, default `0664`)
|
|
87
|
+
- `geometry` - Map size/geometry options (optional)
|
|
80
88
|
|
|
81
89
|
Note: When `keyFlag` or `valueFlag` are set at environment level, they become defaults for all subsequent operations unless explicitly overridden.
|
|
82
90
|
|
|
@@ -124,14 +132,14 @@ const result = await env.query([
|
|
|
124
132
|
|
|
125
133
|
#### Methods
|
|
126
134
|
|
|
127
|
-
**createMap(keyMode, [valueMode], [
|
|
135
|
+
**createMap(db_name | keyMode, [keyMode | valueMode], [valueMode]) → DBI**
|
|
128
136
|
```javascript
|
|
129
|
-
// No arguments - default keyMode (0) and valueMode (0)
|
|
130
|
-
const dbi = txn.createMap();
|
|
131
|
-
|
|
132
137
|
// One argument - keyMode only
|
|
133
138
|
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
134
139
|
|
|
140
|
+
// One argument - db_name only (uses default keyMode)
|
|
141
|
+
const namedDbi = txn.createMap("my-table");
|
|
142
|
+
|
|
135
143
|
// Two arguments - keyMode + valueMode
|
|
136
144
|
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal, MDBX_Param.valueMode.multi);
|
|
137
145
|
|
|
@@ -144,17 +152,17 @@ const namedDbi = txn.createMap("my-table", MDBX_Param.keyMode.ordinal, MDBX_Para
|
|
|
144
152
|
|
|
145
153
|
> **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
154
|
|
|
147
|
-
**openMap(keyMode, [
|
|
155
|
+
**openMap(db_name | keyMode, [keyMode]) → DBI**
|
|
148
156
|
```javascript
|
|
149
|
-
// No arguments - default keyMode (0)
|
|
150
|
-
const dbi = txn.openMap();
|
|
151
|
-
|
|
152
157
|
// One argument - keyMode only
|
|
153
158
|
// Number keyMode - keys returned as numbers
|
|
154
159
|
const dbi = txn.openMap(MDBX_Param.keyMode.ordinal);
|
|
155
160
|
// BigInt keyMode - keys returned as BigInts
|
|
156
161
|
const dbi = txn.openMap(BigInt(MDBX_Param.keyMode.ordinal));
|
|
157
162
|
|
|
163
|
+
// One argument - db_name only (uses default keyMode)
|
|
164
|
+
const namedDbi = txn.openMap("my-table");
|
|
165
|
+
|
|
158
166
|
// Two arguments - db_name + keyMode
|
|
159
167
|
const namedDbi = txn.openMap("my-table", MDBX_Param.keyMode.ordinal);
|
|
160
168
|
const namedDbiBigInt = txn.openMap("my-table", BigInt(MDBX_Param.keyMode.ordinal));
|
|
@@ -454,24 +462,27 @@ async function queryExample() {
|
|
|
454
462
|
const env = new MDBX_Env();
|
|
455
463
|
await env.open({ path: './query-data' });
|
|
456
464
|
|
|
457
|
-
//
|
|
465
|
+
// Create DBI first in synchronous transaction
|
|
466
|
+
const writeTxn = env.startWrite();
|
|
467
|
+
const dbi = writeTxn.createMap(MDBX_Param.keyMode.ordinal);
|
|
468
|
+
writeTxn.commit();
|
|
469
|
+
|
|
470
|
+
// Async query with DBI object (not database name)
|
|
458
471
|
const results = await env.query([
|
|
459
472
|
{
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
mode: MDBX_Param.queryMode.put,
|
|
473
|
+
dbi: dbi,
|
|
474
|
+
mode: MDBX_Param.queryMode.insertUnique,
|
|
463
475
|
item: [
|
|
464
|
-
{ key:
|
|
465
|
-
{ key:
|
|
476
|
+
{ key: 1, value: JSON.stringify({ name: "Alice" }) },
|
|
477
|
+
{ key: 2, value: JSON.stringify({ name: "Bob" }) }
|
|
466
478
|
]
|
|
467
479
|
},
|
|
468
480
|
{
|
|
469
|
-
|
|
470
|
-
dbMode: MDBX_Param.dbMode.accede,
|
|
481
|
+
dbi: dbi,
|
|
471
482
|
mode: MDBX_Param.queryMode.get,
|
|
472
483
|
item: [
|
|
473
|
-
{ key:
|
|
474
|
-
{ key:
|
|
484
|
+
{ key: 1 },
|
|
485
|
+
{ key: 2 }
|
|
475
486
|
]
|
|
476
487
|
}
|
|
477
488
|
]);
|
|
@@ -481,6 +492,47 @@ async function queryExample() {
|
|
|
481
492
|
}
|
|
482
493
|
```
|
|
483
494
|
|
|
495
|
+
### Async Keys API
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
const { MDBX_Env, MDBX_Param } = require('mdbxmou');
|
|
499
|
+
|
|
500
|
+
async function keysExample() {
|
|
501
|
+
const env = new MDBX_Env();
|
|
502
|
+
await env.open({ path: './keys-data' });
|
|
503
|
+
|
|
504
|
+
// Create DBI first
|
|
505
|
+
const writeTxn = env.startWrite();
|
|
506
|
+
const dbi = writeTxn.createMap(MDBX_Param.keyMode.ordinal);
|
|
507
|
+
|
|
508
|
+
// Add some test data
|
|
509
|
+
for (let i = 1; i <= 10; i++) {
|
|
510
|
+
dbi.put(writeTxn, i, `value-${i}`);
|
|
511
|
+
}
|
|
512
|
+
writeTxn.commit();
|
|
513
|
+
|
|
514
|
+
// Get all keys from DBI
|
|
515
|
+
const allKeys = await env.keys(dbi);
|
|
516
|
+
console.log("All keys:", allKeys);
|
|
517
|
+
|
|
518
|
+
// Get keys with DBI object parameter
|
|
519
|
+
const allKeys2 = await env.keys({ dbi: dbi });
|
|
520
|
+
console.log("All keys (object):", allKeys2);
|
|
521
|
+
|
|
522
|
+
// Get keys from multiple DBIs
|
|
523
|
+
const multiKeys = await env.keys([dbi, dbi]);
|
|
524
|
+
console.log("Multi DBI keys:", multiKeys);
|
|
525
|
+
|
|
526
|
+
// Get limited keys from specific position
|
|
527
|
+
const limitedKeys = await env.keys([
|
|
528
|
+
{ dbi: dbi, limit: 3, from: 5 }
|
|
529
|
+
]);
|
|
530
|
+
console.log("Limited keys:", limitedKeys);
|
|
531
|
+
|
|
532
|
+
await env.close();
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
484
536
|
## Error Handling
|
|
485
537
|
|
|
486
538
|
```javascript
|
|
@@ -492,7 +544,7 @@ try {
|
|
|
492
544
|
const dbi = txn.createMap(MDBX_Param.keyMode.ordinal);
|
|
493
545
|
|
|
494
546
|
// This might throw if key already exists with MDBX_NOOVERWRITE
|
|
495
|
-
dbi.put(txn, 123, "value"
|
|
547
|
+
dbi.put(txn, 123, "value");
|
|
496
548
|
|
|
497
549
|
txn.commit();
|
|
498
550
|
} catch (error) {
|
|
@@ -524,7 +576,17 @@ Note: For ordinal (integer) keys, use keyFlag.number or keyFlag.bigint to specif
|
|
|
524
576
|
|
|
525
577
|
### Environment Flags
|
|
526
578
|
- `MDBX_Param.envFlag.nostickythreads` - Don't stick reader transactions to threads
|
|
527
|
-
- `MDBX_Param.envFlag.
|
|
579
|
+
- `MDBX_Param.envFlag.rdonly` - Open database in read-only mode
|
|
580
|
+
- `MDBX_Param.envFlag.validation` - Enable page validation
|
|
581
|
+
- `MDBX_Param.envFlag.exclusive` - Exclusive mode
|
|
582
|
+
- `MDBX_Param.envFlag.accede` - Open existing environment
|
|
583
|
+
- `MDBX_Param.envFlag.writemap` - Use writable memory map
|
|
584
|
+
- `MDBX_Param.envFlag.nordahead` - Disable OS readahead
|
|
585
|
+
- `MDBX_Param.envFlag.nomeminit` - Disable memory initialization
|
|
586
|
+
- `MDBX_Param.envFlag.liforeclaim` - LIFO reclaim
|
|
587
|
+
- `MDBX_Param.envFlag.nometasync` - Disable metadata flushes
|
|
588
|
+
- `MDBX_Param.envFlag.safeNosync` - Safe nosync mode
|
|
589
|
+
- `MDBX_Param.envFlag.utterlyNosync` - Utterly nosync mode
|
|
528
590
|
|
|
529
591
|
### Database Modes
|
|
530
592
|
- `MDBX_Param.dbMode.create` - Create database if it doesn't exist
|
|
@@ -532,9 +594,24 @@ Note: For ordinal (integer) keys, use keyFlag.number or keyFlag.bigint to specif
|
|
|
532
594
|
|
|
533
595
|
### Query Modes
|
|
534
596
|
- `MDBX_Param.queryMode.get` - Read operations
|
|
535
|
-
- `MDBX_Param.queryMode.
|
|
597
|
+
- `MDBX_Param.queryMode.upsert` - Write operations (insert or update)
|
|
598
|
+
- `MDBX_Param.queryMode.update` - Update existing (MDBX_CURRENT)
|
|
599
|
+
- `MDBX_Param.queryMode.insertUnique` - Insert unique (MDBX_NOOVERWRITE)
|
|
536
600
|
- `MDBX_Param.queryMode.del` - Delete operations
|
|
537
601
|
|
|
602
|
+
### Cursor Modes
|
|
603
|
+
- `MDBX_Param.cursorMode.first` - First key
|
|
604
|
+
- `MDBX_Param.cursorMode.last` - Last key
|
|
605
|
+
- `MDBX_Param.cursorMode.next` - Next key
|
|
606
|
+
- `MDBX_Param.cursorMode.prev` - Previous key
|
|
607
|
+
- `MDBX_Param.cursorMode.keyLesserThan` - Keys less than target
|
|
608
|
+
- `MDBX_Param.cursorMode.keyLesserOrEqual` - Keys less than or equal to target
|
|
609
|
+
- `MDBX_Param.cursorMode.keyEqual` - Keys exactly equal to target
|
|
610
|
+
- `MDBX_Param.cursorMode.keyGreaterOrEqual` - Keys greater than or equal to target
|
|
611
|
+
- `MDBX_Param.cursorMode.keyGreaterThan` - Keys greater than target
|
|
612
|
+
|
|
613
|
+
> **Note**: Cursor modes can be used with `keysFrom()` and `forEach()` methods to control iteration direction and filtering.
|
|
614
|
+
|
|
538
615
|
## Performance Tips
|
|
539
616
|
|
|
540
617
|
1. **Use ordinal keys** for integer data - much faster than string keys
|
|
@@ -549,5 +626,5 @@ Apache License 2.0
|
|
|
549
626
|
|
|
550
627
|
---
|
|
551
628
|
|
|
552
|
-
**Documentation generated by GitHub Copilot (Claude 3.5 Sonnet) on August
|
|
629
|
+
**Documentation generated by GitHub Copilot (Claude 3.5 Sonnet) on August 27, 2025**
|
|
553
630
|
**Reviewed and approved by the library author**
|
package/build.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
var spawnSync = require('child_process').spawnSync;
|
|
3
3
|
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
4
5
|
|
|
5
6
|
function exec(cmd) {
|
|
6
7
|
const { status } = spawnSync(cmd, {
|
|
@@ -14,6 +15,7 @@ function exec(cmd) {
|
|
|
14
15
|
|
|
15
16
|
// Create VERSION.json for libmdbx (needed for npm package)
|
|
16
17
|
const versionFile = 'deps/libmdbx/VERSION.json';
|
|
18
|
+
const libmdbxGitMarker = 'deps/libmdbx/.git';
|
|
17
19
|
if (!fs.existsSync(versionFile)) {
|
|
18
20
|
console.log('Creating VERSION.json for libmdbx...');
|
|
19
21
|
const versionJson = {
|
|
@@ -27,14 +29,20 @@ if (!fs.existsSync(versionFile)) {
|
|
|
27
29
|
console.log('VERSION.json created successfully!');
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
//
|
|
32
|
+
// Workaround for npm package: npm does not ship git metadata, while libmdbx
|
|
33
|
+
// may rely on it to determine version info during CMake configure.
|
|
34
|
+
// Apply this patch only when git metadata is missing.
|
|
31
35
|
const cmakeFile = 'deps/libmdbx/CMakeLists.txt';
|
|
32
|
-
if (fs.existsSync(cmakeFile)) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
if (!fs.existsSync(libmdbxGitMarker) && fs.existsSync(cmakeFile)) {
|
|
37
|
+
const cmakeText = fs.readFileSync(cmakeFile, 'utf8');
|
|
38
|
+
const from = 'if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git"';
|
|
39
|
+
const to = 'if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git"';
|
|
40
|
+
if (cmakeText.includes(from)) {
|
|
41
|
+
const patched = cmakeText.replace(from, to);
|
|
42
|
+
if (patched !== cmakeText) {
|
|
43
|
+
fs.writeFileSync(cmakeFile, patched);
|
|
44
|
+
console.log('Patched libmdbx CMakeLists.txt for npm package (no .git).');
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
48
|
|
package/lib/async.mjs
ADDED
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const native = require("./nativemou.js");
|
|
6
|
+
const { MDBX_Async_Env } = require("./mdbx_evn_async.js");
|
|
7
|
+
|
|
8
|
+
export const MDBX_Env = native.MDBX_Env;
|
|
9
|
+
export const MDBX_Param = native.MDBX_Param;
|
|
10
|
+
export { MDBX_Async_Env };
|
|
11
|
+
|
|
12
|
+
export default native;
|
package/lib/mdbx_worker.js
CHANGED
|
@@ -82,17 +82,21 @@ async function handler(msg) {
|
|
|
82
82
|
|
|
83
83
|
case "dbi_put": {
|
|
84
84
|
const { txnId, dbiId, key, value, flags = 0 } = params;
|
|
85
|
+
const t = txns.get(txnId);
|
|
86
|
+
if (!t) throw new Error("no txn");
|
|
85
87
|
const d = dbis.get(dbiId);
|
|
86
88
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
87
|
-
d.dbi.put(key, value, flags);
|
|
89
|
+
d.dbi.put(t.txn, key, value, flags);
|
|
88
90
|
return ok(id, true);
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
case "dbi_get": {
|
|
92
94
|
const { txnId, dbiId, key } = params;
|
|
95
|
+
const t = txns.get(txnId);
|
|
96
|
+
if (!t) throw new Error("no txn");
|
|
93
97
|
const d = dbis.get(dbiId);
|
|
94
98
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
95
|
-
const val = d.dbi.get(key);
|
|
99
|
+
const val = d.dbi.get(t.txn, key);
|
|
96
100
|
// Если val это Buffer, преобразуем в строку для удобства
|
|
97
101
|
const result = (val && Buffer.isBuffer(val)) ? val.toString() : val;
|
|
98
102
|
return ok(id, result);
|
|
@@ -100,25 +104,31 @@ async function handler(msg) {
|
|
|
100
104
|
|
|
101
105
|
case "dbi_del": {
|
|
102
106
|
const { txnId, dbiId, key } = params;
|
|
107
|
+
const t = txns.get(txnId);
|
|
108
|
+
if (!t) throw new Error("no txn");
|
|
103
109
|
const d = dbis.get(dbiId);
|
|
104
110
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
105
|
-
const r = d.dbi.del(key);
|
|
111
|
+
const r = d.dbi.del(t.txn, key);
|
|
106
112
|
return ok(id, r);
|
|
107
113
|
}
|
|
108
114
|
|
|
109
115
|
case "dbi_stat": {
|
|
110
116
|
const { txnId, dbiId } = params;
|
|
117
|
+
const t = txns.get(txnId);
|
|
118
|
+
if (!t) throw new Error("no txn");
|
|
111
119
|
const d = dbis.get(dbiId);
|
|
112
120
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
113
|
-
return ok(id, d.dbi.stat());
|
|
121
|
+
return ok(id, d.dbi.stat(t.txn));
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
case "dbi_iter_all": {
|
|
117
125
|
const { txnId, dbiId } = params;
|
|
126
|
+
const t = txns.get(txnId);
|
|
127
|
+
if (!t) throw new Error("no txn");
|
|
118
128
|
const d = dbis.get(dbiId);
|
|
119
129
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
120
130
|
const out = [];
|
|
121
|
-
d.dbi.forEach((k, v) => {
|
|
131
|
+
d.dbi.forEach(t.txn, (k, v) => {
|
|
122
132
|
out.push({ key: k, value: v });
|
|
123
133
|
return true;
|
|
124
134
|
});
|
|
@@ -128,13 +138,15 @@ async function handler(msg) {
|
|
|
128
138
|
case "dbi_get_batch": {
|
|
129
139
|
// Групповое чтение множества ключей
|
|
130
140
|
const { txnId, dbiId, keys } = params;
|
|
141
|
+
const t = txns.get(txnId);
|
|
142
|
+
if (!t) throw new Error("no txn");
|
|
131
143
|
const d = dbis.get(dbiId);
|
|
132
144
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
133
145
|
|
|
134
146
|
const results = [];
|
|
135
147
|
for (const key of keys) {
|
|
136
148
|
try {
|
|
137
|
-
const val = d.dbi.get(key);
|
|
149
|
+
const val = d.dbi.get(t.txn, key);
|
|
138
150
|
if (val !== undefined && val !== null) {
|
|
139
151
|
const result = (val && Buffer.isBuffer(val)) ? val.toString() : val;
|
|
140
152
|
results.push({ key, value: result, found: true });
|
|
@@ -151,13 +163,15 @@ async function handler(msg) {
|
|
|
151
163
|
case "dbi_put_batch": {
|
|
152
164
|
// Групповая запись множества пар ключ-значение
|
|
153
165
|
const { txnId, dbiId, items, flags = 0 } = params;
|
|
166
|
+
const t = txns.get(txnId);
|
|
167
|
+
if (!t) throw new Error("no txn");
|
|
154
168
|
const d = dbis.get(dbiId);
|
|
155
169
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
156
170
|
|
|
157
171
|
const results = [];
|
|
158
172
|
for (const item of items) {
|
|
159
173
|
try {
|
|
160
|
-
d.dbi.put(item.key, item.value, flags);
|
|
174
|
+
d.dbi.put(t.txn, item.key, item.value, flags);
|
|
161
175
|
results.push({ key: item.key, success: true });
|
|
162
176
|
} catch (e) {
|
|
163
177
|
results.push({ key: item.key, success: false, error: e.message });
|
|
@@ -169,13 +183,15 @@ async function handler(msg) {
|
|
|
169
183
|
case "dbi_del_batch": {
|
|
170
184
|
// Групповое удаление множества ключей
|
|
171
185
|
const { txnId, dbiId, keys } = params;
|
|
186
|
+
const t = txns.get(txnId);
|
|
187
|
+
if (!t) throw new Error("no txn");
|
|
172
188
|
const d = dbis.get(dbiId);
|
|
173
189
|
if (!d || d.txnId !== txnId) throw new Error("no dbi");
|
|
174
190
|
|
|
175
191
|
const results = [];
|
|
176
192
|
for (const key of keys) {
|
|
177
193
|
try {
|
|
178
|
-
const r = d.dbi.del(key);
|
|
194
|
+
const r = d.dbi.del(t.txn, key);
|
|
179
195
|
results.push({ key, deleted: r });
|
|
180
196
|
} catch (e) {
|
|
181
197
|
results.push({ key, deleted: false, error: e.message });
|
package/package.json
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"main": "lib/nativemou.js",
|
|
3
|
+
"exports": {
|
|
4
|
+
".": {
|
|
5
|
+
"import": "./lib/index.mjs",
|
|
6
|
+
"require": "./lib/nativemou.js"
|
|
7
|
+
},
|
|
8
|
+
"./async": {
|
|
9
|
+
"import": "./lib/async.mjs",
|
|
10
|
+
"require": "./lib/mdbx_evn_async.js"
|
|
11
|
+
},
|
|
12
|
+
"./nativemou": "./lib/nativemou.js",
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
3
15
|
"files": [
|
|
4
16
|
"lib/**/*",
|
|
5
17
|
"src/**/*",
|
|
@@ -18,6 +30,7 @@
|
|
|
18
30
|
"e3": "node ./test/e3.js",
|
|
19
31
|
"e33": "node ./test/e33.js",
|
|
20
32
|
"e4": "node ./test/e4.js",
|
|
33
|
+
"e4async": "node ./test/e4async.mjs",
|
|
21
34
|
"e5": "node ./test/e5.js",
|
|
22
35
|
"build": "node build.js",
|
|
23
36
|
"build-dev": "node build-dev.js",
|
|
@@ -25,7 +38,7 @@
|
|
|
25
38
|
},
|
|
26
39
|
"gypfile": true,
|
|
27
40
|
"name": "mdbxmou",
|
|
28
|
-
"version": "0.2.
|
|
41
|
+
"version": "0.2.4",
|
|
29
42
|
"description": "Node bindings for mdbx",
|
|
30
43
|
"repository": {
|
|
31
44
|
"type": "git",
|
|
@@ -10,16 +10,7 @@ void async_keys::Execute()
|
|
|
10
10
|
// стартуем транзакцию
|
|
11
11
|
auto txn = start_transaction();
|
|
12
12
|
for (auto& req : query_)
|
|
13
|
-
|
|
14
|
-
mdbx::map_handle dbi{};
|
|
15
|
-
auto db_mode = req.db_mod;
|
|
16
|
-
if (db_mode.val & db_mode::accede) {
|
|
17
|
-
dbi = txn.open_map_accede(req.db);
|
|
18
|
-
} else {
|
|
19
|
-
dbi = txn.open_map(req.db, req.key_mod, req.val_mod);
|
|
20
|
-
}
|
|
21
|
-
do_keys(txn, dbi, req);
|
|
22
|
-
}
|
|
13
|
+
do_keys(txn, {req.id}, req);
|
|
23
14
|
|
|
24
15
|
txn.commit();
|
|
25
16
|
} catch (const std::exception& e) {
|
|
@@ -72,9 +63,6 @@ void async_keys::OnOK()
|
|
|
72
63
|
for (std::uint32_t i = 0; i < query_.size(); ++i) {
|
|
73
64
|
Napi::Object js_row = Napi::Object::New(env);
|
|
74
65
|
const auto& row = query_[i];
|
|
75
|
-
if (!row.db.empty()) {
|
|
76
|
-
js_row.Set("db", Napi::String::New(env, row.db_name));
|
|
77
|
-
}
|
|
78
66
|
result.Set(i, write_row(env, row));
|
|
79
67
|
}
|
|
80
68
|
|
|
@@ -10,16 +10,7 @@ void async_query::Execute()
|
|
|
10
10
|
auto txn = start_transaction();
|
|
11
11
|
for (auto& req : query_)
|
|
12
12
|
{
|
|
13
|
-
mdbx::map_handle dbi{};
|
|
14
|
-
auto db_mode = req.db_mod;
|
|
15
|
-
if (db_mode.val & db_mode::accede) {
|
|
16
|
-
dbi = txn.open_map_accede(req.db);
|
|
17
|
-
} else if (db_mode.val & db_mode::create) {
|
|
18
|
-
dbi = txn.create_map(req.db, req.key_mod, req.val_mod);
|
|
19
|
-
} else {
|
|
20
|
-
dbi = txn.open_map(req.db, req.key_mod, req.val_mod);
|
|
21
|
-
}
|
|
22
|
-
|
|
13
|
+
mdbx::map_handle dbi{req.id};
|
|
23
14
|
auto mode = req.mode;
|
|
24
15
|
if (mode.val & query_mode::get) {
|
|
25
16
|
do_get(txn, dbi, req);
|
|
@@ -29,7 +20,6 @@ void async_query::Execute()
|
|
|
29
20
|
do_put(txn, dbi, req);
|
|
30
21
|
}
|
|
31
22
|
}
|
|
32
|
-
|
|
33
23
|
txn.commit();
|
|
34
24
|
} catch (const std::exception& e) {
|
|
35
25
|
SetError(e.what());
|
|
@@ -111,9 +101,6 @@ void async_query::OnOK()
|
|
|
111
101
|
for (std::size_t i = 0; i < query_.size(); ++i) {
|
|
112
102
|
Napi::Object js_row = Napi::Object::New(env);
|
|
113
103
|
const auto& row = query_[i];
|
|
114
|
-
if (!row.db.empty()) {
|
|
115
|
-
js_row.Set("db", Napi::String::New(env, row.db_name));
|
|
116
|
-
}
|
|
117
104
|
result.Set(static_cast<uint32_t>(i), write_row(env, row));
|
|
118
105
|
}
|
|
119
106
|
|
package/src/dbimou.cpp
CHANGED
|
@@ -569,13 +569,11 @@ Napi::Value dbimou::keys_from(const Napi::CallbackInfo& info) {
|
|
|
569
569
|
Napi::Value dbimou::drop(const Napi::CallbackInfo& info) {
|
|
570
570
|
Napi::Env env = info.Env();
|
|
571
571
|
if (info.Length() < 1) {
|
|
572
|
-
Napi::TypeError::New(env, "First argument must be a transaction")
|
|
573
|
-
return env.Undefined();
|
|
572
|
+
throw Napi::TypeError::New(env, "First argument must be a transaction");
|
|
574
573
|
}
|
|
575
574
|
auto arg0 = info[0].As<Napi::Object>();
|
|
576
575
|
if (!arg0.InstanceOf(txnmou::ctor.Value())) {
|
|
577
|
-
Napi::TypeError::New(env, "First argument must be a txnmou instance")
|
|
578
|
-
return env.Undefined();
|
|
576
|
+
throw Napi::TypeError::New(env, "First argument must be a txnmou instance");
|
|
579
577
|
}
|
|
580
578
|
auto txn = Napi::ObjectWrap<txnmou>::Unwrap(arg0);
|
|
581
579
|
bool delete_db = false;
|
package/src/dbimou.hpp
CHANGED
|
@@ -24,7 +24,6 @@ class dbimou final
|
|
|
24
24
|
|
|
25
25
|
buffer_type key_buf_{};
|
|
26
26
|
buffer_type val_buf_{};
|
|
27
|
-
std::uint64_t id_buf_{};
|
|
28
27
|
|
|
29
28
|
public:
|
|
30
29
|
static Napi::FunctionReference ctor;
|
|
@@ -60,6 +59,9 @@ public:
|
|
|
60
59
|
|
|
61
60
|
static void init(const char *class_name, Napi::Env env);
|
|
62
61
|
|
|
62
|
+
// valuemou read(const MDBX_txn* txn);
|
|
63
|
+
// valuemou read(const MDBX_txn* txn, const keymou& key);
|
|
64
|
+
|
|
63
65
|
// Основные операции (только синхронные)
|
|
64
66
|
Napi::Value put(const Napi::CallbackInfo&);
|
|
65
67
|
Napi::Value get(const Napi::CallbackInfo&);
|
|
@@ -69,7 +71,7 @@ public:
|
|
|
69
71
|
Napi::Value stat(const Napi::CallbackInfo&);
|
|
70
72
|
Napi::Value keys(const Napi::CallbackInfo&);
|
|
71
73
|
Napi::Value keys_from(const Napi::CallbackInfo&);
|
|
72
|
-
Napi::Value drop(const Napi::CallbackInfo&
|
|
74
|
+
Napi::Value drop(const Napi::CallbackInfo&);
|
|
73
75
|
|
|
74
76
|
private:
|
|
75
77
|
// Внутренний метод для forEach с начальным ключом
|
|
@@ -92,6 +94,30 @@ public:
|
|
|
92
94
|
operator MDBX_put_flags_t() const noexcept {
|
|
93
95
|
return static_cast<MDBX_put_flags_t>(key_mode_.val & value_mode_.val);
|
|
94
96
|
}
|
|
97
|
+
|
|
98
|
+
MDBX_dbi get_id() const noexcept {
|
|
99
|
+
return id_;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
db_mode get_mode() const noexcept {
|
|
103
|
+
return mode_;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
key_mode get_key_mode() const noexcept {
|
|
107
|
+
return key_mode_;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
value_mode get_value_mode() const noexcept {
|
|
111
|
+
return value_mode_;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
base_flag get_key_flag() const noexcept {
|
|
115
|
+
return key_flag_;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
base_flag get_value_flag() const noexcept {
|
|
119
|
+
return value_flag_;
|
|
120
|
+
}
|
|
95
121
|
};
|
|
96
122
|
|
|
97
123
|
} // namespace mdbxmou
|
package/src/envmou.cpp
CHANGED
|
@@ -372,8 +372,7 @@ Napi::Value envmou::query(const Napi::CallbackInfo& info)
|
|
|
372
372
|
txn_mode mode{};
|
|
373
373
|
|
|
374
374
|
if (info.Length() < 1) {
|
|
375
|
-
throw Napi::TypeError::New(env,
|
|
376
|
-
"expected array of requests: [{ db: String, db_mode: Number, key_mode: Number, key_flag: Number, value_mode: Number, value_flag: Number, mode: Number, item: [] }, ...]");
|
|
375
|
+
throw Napi::TypeError::New(env, "expected array of requests");
|
|
377
376
|
}
|
|
378
377
|
|
|
379
378
|
if (info.Length() > 1 || info[1].IsNumber()) {
|
|
@@ -389,8 +388,7 @@ Napi::Value envmou::query(const Napi::CallbackInfo& info)
|
|
|
389
388
|
auto conf = get_env_userctx(*this);
|
|
390
389
|
|
|
391
390
|
auto arg0 = info[0];
|
|
392
|
-
query_request query = parse_query(mode,
|
|
393
|
-
conf->key_flag, conf->value_flag, arg0);
|
|
391
|
+
query_request query = parse_query(mode, arg0);
|
|
394
392
|
auto* worker = new async_query(env, *this, mode,
|
|
395
393
|
std::move(query), arg0.IsObject());
|
|
396
394
|
auto promise = worker->GetPromise();
|
|
@@ -429,11 +427,8 @@ Napi::Value envmou::keys(const Napi::CallbackInfo& info)
|
|
|
429
427
|
|
|
430
428
|
check();
|
|
431
429
|
|
|
432
|
-
auto conf = get_env_userctx(*this);
|
|
433
|
-
|
|
434
430
|
auto arg0 = info[0];
|
|
435
|
-
keys_request query = parse_keys(
|
|
436
|
-
conf->key_flag, conf->value_flag, arg0);
|
|
431
|
+
keys_request query = parse_keys(arg0);
|
|
437
432
|
|
|
438
433
|
auto* worker = new async_keys(env, *this, mode,
|
|
439
434
|
std::move(query), arg0.IsObject());
|
package/src/modulemou.cpp
CHANGED
|
@@ -78,24 +78,24 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
|
78
78
|
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "last", move_operation::last);
|
|
79
79
|
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "next", move_operation::next);
|
|
80
80
|
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "prev", move_operation::previous);
|
|
81
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
81
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "keyLesserThan",
|
|
82
82
|
move_operation::key_lesser_than);
|
|
83
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
83
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "keyLesserOrEqual",
|
|
84
84
|
move_operation::key_lesser_or_equal);
|
|
85
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
86
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
85
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "keyEqual", move_operation::key_equal);
|
|
86
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "keyGreaterOrEqual",
|
|
87
87
|
move_operation::key_greater_or_equal);
|
|
88
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
88
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "keyGreaterThan",
|
|
89
89
|
move_operation::key_greater_than);
|
|
90
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
90
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "multiExactKeyValueLesserThan",
|
|
91
91
|
move_operation::multi_exactkey_value_lesser_than);
|
|
92
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
92
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "multiExactKeyValueLesserOrEqual",
|
|
93
93
|
move_operation::multi_exactkey_value_lesser_or_equal);
|
|
94
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
94
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "multiExactKeyValueEqual",
|
|
95
95
|
move_operation::multi_exactkey_value_equal);
|
|
96
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
96
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "multiExactKeyValueGreaterOrEqual",
|
|
97
97
|
move_operation::multi_exactkey_value_greater_or_equal);
|
|
98
|
-
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "
|
|
98
|
+
MDBXMOU_DECLARE_FLAG_NAME(cursor_mode, "multiExactKeyValueGreater",
|
|
99
99
|
move_operation::multi_exactkey_value_greater);
|
|
100
100
|
mdbx_mou.Set("cursorMode", cursor_mode);
|
|
101
101
|
|
package/src/querymou.cpp
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
1
|
#include "querymou.hpp"
|
|
2
|
+
#include "dbimou.hpp"
|
|
2
3
|
|
|
3
4
|
namespace mdbxmou {
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
dbimou* async_common::parse(const Napi::Object& arg0)
|
|
6
7
|
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (obj.Has("keyFlag")) {
|
|
17
|
-
key_flag = base_flag::parse_key(obj.Get("keyFlag").As<Napi::Number>());
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (obj.Has("keyMode")) {
|
|
21
|
-
key_mod = parse_key_mode(obj.Env(), obj.Get("keyMode").As<Napi::Number>(), key_flag);
|
|
8
|
+
dbimou* dbi = nullptr;
|
|
9
|
+
// если просто передали dbi
|
|
10
|
+
if (arg0.InstanceOf(dbimou::ctor.Value())) {
|
|
11
|
+
dbi = Napi::ObjectWrap<dbimou>::Unwrap(arg0);
|
|
12
|
+
} else {
|
|
13
|
+
auto t = arg0.Get("dbi").As<Napi::Object>();
|
|
14
|
+
dbi = Napi::ObjectWrap<dbimou>::Unwrap(t);
|
|
22
15
|
}
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
id = dbi->get_id();
|
|
18
|
+
key_mod = dbi->get_key_mode();
|
|
19
|
+
val_mod = dbi->get_value_mode();
|
|
20
|
+
key_flag = dbi->get_key_flag();
|
|
21
|
+
return dbi;
|
|
28
22
|
}
|
|
29
23
|
|
|
30
24
|
void async_key::parse(const async_common& common, const Napi::Value& item)
|
|
@@ -59,101 +53,75 @@ void async_keyval::parse(const query_line& common, const Napi::Object& item)
|
|
|
59
53
|
}
|
|
60
54
|
}
|
|
61
55
|
|
|
62
|
-
void query_line::parse(txn_mode txn, const Napi::Object&
|
|
56
|
+
void query_line::parse(txn_mode txn, const Napi::Object& arg0)
|
|
63
57
|
{
|
|
64
58
|
// парсим общие параметры
|
|
65
|
-
async_common::parse(
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
void query_line::parse(txn_mode txn, base_flag kf,
|
|
80
|
-
base_flag vf, const Napi::Object& obj)
|
|
81
|
-
{
|
|
82
|
-
// утснавлиаем общие параметры
|
|
83
|
-
this->key_flag = kf;
|
|
84
|
-
this->value_flag = vf;
|
|
85
|
-
|
|
86
|
-
// парсим общие параметры
|
|
87
|
-
parse(txn, obj);
|
|
88
|
-
|
|
89
|
-
// Парсим элементы
|
|
90
|
-
if (obj.Has("item")) {
|
|
91
|
-
auto items_array = obj.Get("item").As<Napi::Array>();
|
|
92
|
-
auto length = items_array.Length();
|
|
93
|
-
item.reserve(length);
|
|
94
|
-
for (uint32_t i = 0; i < length; ++i) {
|
|
59
|
+
auto dbi = async_common::parse(arg0);
|
|
60
|
+
value_flag = dbi->get_value_flag();
|
|
61
|
+
if (arg0.Has("mode")) {
|
|
62
|
+
mode = query_mode::parse(txn, arg0.Get("mode").As<Napi::Number>());
|
|
63
|
+
} else if (arg0.Has("queryMode")) {
|
|
64
|
+
mode = query_mode::parse(txn, arg0.Get("queryMode").As<Napi::Number>());
|
|
65
|
+
}
|
|
66
|
+
auto items_array = arg0.Get("item").As<Napi::Array>();
|
|
67
|
+
auto item_len = items_array.Length();
|
|
68
|
+
if (item_len > 0) {
|
|
69
|
+
item.reserve(item_len);
|
|
70
|
+
for (uint32_t i = 0; i < item_len; ++i) {
|
|
95
71
|
auto item_obj = items_array.Get(i).As<Napi::Object>();
|
|
96
72
|
async_keyval keyval{};
|
|
97
73
|
keyval.parse(*this, item_obj);
|
|
98
74
|
item.emplace_back(std::move(keyval));
|
|
99
75
|
}
|
|
100
|
-
} else {
|
|
101
|
-
throw std::runtime_error("query: no item");
|
|
102
76
|
}
|
|
103
77
|
}
|
|
104
78
|
|
|
105
|
-
query_request parse_query(txn_mode
|
|
106
|
-
base_flag value_flag, const Napi::Value& obj)
|
|
79
|
+
query_request parse_query(txn_mode txn, const Napi::Value& arg0)
|
|
107
80
|
{
|
|
108
81
|
query_request rc{};
|
|
109
|
-
if (
|
|
110
|
-
auto arr =
|
|
82
|
+
if (arg0.IsArray()) {
|
|
83
|
+
auto arr = arg0.As<Napi::Array>();
|
|
111
84
|
rc.reserve(arr.Length());
|
|
112
85
|
for (uint32_t i = 0; i < arr.Length(); ++i) {
|
|
113
86
|
query_line row{};
|
|
114
|
-
row.parse(
|
|
87
|
+
row.parse(txn, arr.Get(i).As<Napi::Object>());
|
|
115
88
|
rc.push_back(std::move(row));
|
|
116
89
|
}
|
|
117
|
-
} else if (
|
|
90
|
+
} else if (arg0.IsObject()) {
|
|
118
91
|
query_line row{};
|
|
119
|
-
row.parse(
|
|
92
|
+
row.parse(txn, arg0.As<Napi::Object>());
|
|
120
93
|
rc.push_back(std::move(row));
|
|
121
94
|
} else {
|
|
122
|
-
throw Napi::TypeError::New(
|
|
95
|
+
throw Napi::TypeError::New(arg0.Env(), "Expected array or object for query");
|
|
123
96
|
}
|
|
124
97
|
return rc;
|
|
125
98
|
}
|
|
126
99
|
|
|
127
|
-
void keys_line::parse(
|
|
128
|
-
base_flag kf, const Napi::Object& obj)
|
|
100
|
+
void keys_line::parse(const Napi::Object& arg0)
|
|
129
101
|
{
|
|
130
|
-
// утснавлиаем общие параметры
|
|
131
|
-
this->key_flag = kf;
|
|
132
|
-
|
|
133
102
|
// парсим общие параметры
|
|
134
|
-
async_common::parse(
|
|
103
|
+
async_common::parse(arg0);
|
|
135
104
|
|
|
136
105
|
// парсим параметры scan_from
|
|
137
|
-
if (
|
|
106
|
+
if (arg0.Has("from")) {
|
|
138
107
|
keymou key{};
|
|
139
108
|
has_from_key = true;
|
|
140
|
-
async_key::parse(*this,
|
|
109
|
+
async_key::parse(*this, arg0.Get("from"));
|
|
141
110
|
}
|
|
142
111
|
|
|
143
|
-
if (
|
|
144
|
-
auto limit_val =
|
|
112
|
+
if (arg0.Has("limit")) {
|
|
113
|
+
auto limit_val = arg0.Get("limit");
|
|
145
114
|
if (limit_val.IsNumber()) {
|
|
146
115
|
limit = limit_val.As<Napi::Number>().Uint32Value();
|
|
147
116
|
}
|
|
148
117
|
}
|
|
149
118
|
|
|
150
|
-
if (
|
|
151
|
-
cursor_mode = parse_cursor_mode(
|
|
119
|
+
if (arg0.Has("cursorMode")) {
|
|
120
|
+
cursor_mode = parse_cursor_mode(arg0.Get("cursorMode"));
|
|
152
121
|
}
|
|
153
122
|
}
|
|
154
123
|
|
|
155
|
-
keys_request parse_keys(
|
|
156
|
-
base_flag value_flag, const Napi::Value& obj)
|
|
124
|
+
keys_request parse_keys(const Napi::Value& obj)
|
|
157
125
|
{
|
|
158
126
|
keys_request rc{};
|
|
159
127
|
if (obj.IsArray()) {
|
|
@@ -161,12 +129,12 @@ keys_request parse_keys(txn_mode txn, base_flag key_flag,
|
|
|
161
129
|
rc.reserve(arr.Length());
|
|
162
130
|
for (uint32_t i = 0; i < arr.Length(); ++i) {
|
|
163
131
|
keys_line row{};
|
|
164
|
-
row.parse(
|
|
132
|
+
row.parse(arr.Get(i).As<Napi::Object>());
|
|
165
133
|
rc.push_back(std::move(row));
|
|
166
134
|
}
|
|
167
135
|
} else if (obj.IsObject()) {
|
|
168
136
|
keys_line row{};
|
|
169
|
-
row.parse(
|
|
137
|
+
row.parse(obj.As<Napi::Object>());
|
|
170
138
|
rc.push_back(std::move(row));
|
|
171
139
|
} else {
|
|
172
140
|
throw Napi::TypeError::New(obj.Env(), "Expected array or object for query");
|
package/src/querymou.hpp
CHANGED
|
@@ -5,28 +5,28 @@
|
|
|
5
5
|
|
|
6
6
|
namespace mdbxmou {
|
|
7
7
|
|
|
8
|
+
class dbimou;
|
|
8
9
|
struct keys_line;
|
|
9
10
|
struct query_line;
|
|
10
11
|
|
|
11
12
|
struct async_common
|
|
12
13
|
{
|
|
13
14
|
// чтобы уметь открыть базу по умолчанию
|
|
14
|
-
|
|
15
|
-
std::string db_name{};
|
|
16
|
-
db_mode db_mod{};
|
|
15
|
+
MDBX_dbi id{};
|
|
17
16
|
// тут важен для нас ordinal он влияет на option_mask
|
|
18
17
|
key_mode key_mod{};
|
|
19
18
|
base_flag key_flag{};
|
|
20
19
|
// общий используется для открытия db
|
|
21
20
|
value_mode val_mod{};
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
dbimou* parse(const Napi::Object& arg0);
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
struct async_key
|
|
27
26
|
{
|
|
28
|
-
buffer_type key_buf{};
|
|
29
27
|
std::uint64_t id_buf{};
|
|
28
|
+
buffer_type key_buf{};
|
|
29
|
+
|
|
30
30
|
void parse(const async_common& common, const Napi::Value& item);
|
|
31
31
|
|
|
32
32
|
void parse(const async_common& common, const Napi::Object& item)
|
|
@@ -57,18 +57,13 @@ struct query_line
|
|
|
57
57
|
{
|
|
58
58
|
base_flag value_flag{};
|
|
59
59
|
query_mode mode{};
|
|
60
|
-
|
|
61
|
-
void parse(txn_mode mode, const Napi::Object& obj);
|
|
62
|
-
|
|
63
60
|
// буффер для запроса / ответа
|
|
64
61
|
std::vector<async_keyval> item{};
|
|
65
|
-
void parse(txn_mode txn,
|
|
66
|
-
base_flag value_flag, const Napi::Object& obj);
|
|
62
|
+
void parse(txn_mode txn, const Napi::Object& arg0);
|
|
67
63
|
};
|
|
68
64
|
|
|
69
65
|
using query_request = std::vector<query_line>;
|
|
70
|
-
query_request parse_query(txn_mode txn,
|
|
71
|
-
base_flag value_flag, const Napi::Value& obj);
|
|
66
|
+
query_request parse_query(txn_mode txn, const Napi::Value& arg0);
|
|
72
67
|
|
|
73
68
|
|
|
74
69
|
struct keys_line
|
|
@@ -82,12 +77,10 @@ struct keys_line
|
|
|
82
77
|
// буффер для ответов
|
|
83
78
|
std::vector<async_key> item{};
|
|
84
79
|
|
|
85
|
-
void parse(
|
|
86
|
-
const Napi::Object& obj);
|
|
80
|
+
void parse(const Napi::Object& arg0);
|
|
87
81
|
};
|
|
88
82
|
|
|
89
83
|
using keys_request = std::vector<keys_line>;
|
|
90
|
-
keys_request parse_keys(
|
|
91
|
-
base_flag value_flag, const Napi::Value& obj);
|
|
84
|
+
keys_request parse_keys(const Napi::Value& obj);
|
|
92
85
|
|
|
93
86
|
} // namespace mdbxmou
|
package/src/txnmou.cpp
CHANGED
|
@@ -251,12 +251,4 @@ void txnmou::free_txn::operator()(MDBX_txn* txn) const noexcept {
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
void txnmou::drop(MDBX_dbi id, bool del)
|
|
255
|
-
{
|
|
256
|
-
auto rc = mdbx_drop(*this, id, del);
|
|
257
|
-
if (rc != MDBX_SUCCESS) {
|
|
258
|
-
throw std::runtime_error(mdbx_strerror(rc));
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
254
|
} // namespace mdbxmou
|
package/src/txnmou.hpp
CHANGED
package/src/typemou.hpp
CHANGED
|
@@ -10,7 +10,7 @@ namespace mdbxmou {
|
|
|
10
10
|
using buffer_type = std::vector<char>;
|
|
11
11
|
|
|
12
12
|
struct txnmou_managed final
|
|
13
|
-
:
|
|
13
|
+
: mdbx::txn_managed
|
|
14
14
|
{
|
|
15
15
|
txnmou_managed(MDBX_txn* txn)
|
|
16
16
|
{
|
|
@@ -19,7 +19,7 @@ struct txnmou_managed final
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
struct cursormou_managed final
|
|
22
|
-
:
|
|
22
|
+
: mdbx::cursor_managed
|
|
23
23
|
{
|
|
24
24
|
cursormou_managed(MDBX_cursor* cursor) noexcept
|
|
25
25
|
{
|