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
|
@@ -0,0 +1,831 @@
|
|
|
1
|
+
/// \copyright SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/// \note Please refer to the COPYRIGHT file for explanations license change,
|
|
3
|
+
/// credits and acknowledgments.
|
|
4
|
+
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
|
|
5
|
+
///
|
|
6
|
+
/// mdbx_load.c - memory-mapped database load tool
|
|
7
|
+
///
|
|
8
|
+
|
|
9
|
+
#ifdef _MSC_VER
|
|
10
|
+
#if _MSC_VER > 1800
|
|
11
|
+
#pragma warning(disable : 4464) /* relative include path contains '..' */
|
|
12
|
+
#endif
|
|
13
|
+
#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
|
|
14
|
+
#endif /* _MSC_VER (warnings) */
|
|
15
|
+
|
|
16
|
+
#define xMDBX_TOOLS /* Avoid using internal eASSERT() */
|
|
17
|
+
#include "essentials.h"
|
|
18
|
+
|
|
19
|
+
#include <ctype.h>
|
|
20
|
+
|
|
21
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
22
|
+
#include "wingetopt.h"
|
|
23
|
+
|
|
24
|
+
static volatile BOOL user_break;
|
|
25
|
+
static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
|
|
26
|
+
(void)dwCtrlType;
|
|
27
|
+
user_break = true;
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#else /* WINDOWS */
|
|
32
|
+
|
|
33
|
+
static volatile sig_atomic_t user_break;
|
|
34
|
+
static void signal_handler(int sig) {
|
|
35
|
+
(void)sig;
|
|
36
|
+
user_break = 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#endif /* !WINDOWS */
|
|
40
|
+
|
|
41
|
+
static char *prog;
|
|
42
|
+
static bool quiet = false;
|
|
43
|
+
static size_t lineno;
|
|
44
|
+
static void error(const char *func, int rc) {
|
|
45
|
+
if (!quiet) {
|
|
46
|
+
if (lineno)
|
|
47
|
+
fprintf(stderr, "%s: at input line %" PRIiSIZE ": %s() error %d, %s\n", prog, lineno, func, rc,
|
|
48
|
+
mdbx_strerror(rc));
|
|
49
|
+
else
|
|
50
|
+
fprintf(stderr, "%s: %s() error %d %s\n", prog, func, rc, mdbx_strerror(rc));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static void logger(MDBX_log_level_t level, const char *function, int line, const char *fmt, va_list args) {
|
|
55
|
+
static const char *const prefixes[] = {
|
|
56
|
+
"!!!fatal: ", // 0 fatal
|
|
57
|
+
" ! ", // 1 error
|
|
58
|
+
" ~ ", // 2 warning
|
|
59
|
+
" ", // 3 notice
|
|
60
|
+
" //", // 4 verbose
|
|
61
|
+
};
|
|
62
|
+
if (level < MDBX_LOG_DEBUG) {
|
|
63
|
+
if (function && line)
|
|
64
|
+
fprintf(stderr, "%s", prefixes[level]);
|
|
65
|
+
vfprintf(stderr, fmt, args);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static char *valstr(char *line, const char *item) {
|
|
70
|
+
const size_t len = strlen(item);
|
|
71
|
+
if (strncmp(line, item, len) != 0)
|
|
72
|
+
return nullptr;
|
|
73
|
+
if (line[len] != '=') {
|
|
74
|
+
if (line[len] > ' ')
|
|
75
|
+
return nullptr;
|
|
76
|
+
if (!quiet)
|
|
77
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected line format for '%s'\n", prog, lineno, item);
|
|
78
|
+
exit(EXIT_FAILURE);
|
|
79
|
+
}
|
|
80
|
+
char *ptr = strchr(line, '\n');
|
|
81
|
+
if (ptr)
|
|
82
|
+
*ptr = '\0';
|
|
83
|
+
return line + len + 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static bool valnum(char *line, const char *item, uint64_t *value) {
|
|
87
|
+
char *str = valstr(line, item);
|
|
88
|
+
if (!str)
|
|
89
|
+
return false;
|
|
90
|
+
|
|
91
|
+
char *end = nullptr;
|
|
92
|
+
*value = strtoull(str, &end, 0);
|
|
93
|
+
if (end && *end) {
|
|
94
|
+
if (!quiet)
|
|
95
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected number format for '%s'\n", prog, lineno, item);
|
|
96
|
+
exit(EXIT_FAILURE);
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static bool valbool(char *line, const char *item, bool *value) {
|
|
102
|
+
uint64_t u64;
|
|
103
|
+
if (!valnum(line, item, &u64))
|
|
104
|
+
return false;
|
|
105
|
+
|
|
106
|
+
if (u64 > 1) {
|
|
107
|
+
if (!quiet)
|
|
108
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected value for '%s'\n", prog, lineno, item);
|
|
109
|
+
exit(EXIT_FAILURE);
|
|
110
|
+
}
|
|
111
|
+
*value = u64 != 0;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/*----------------------------------------------------------------------------*/
|
|
116
|
+
|
|
117
|
+
static char *subname = nullptr;
|
|
118
|
+
static int dbi_flags;
|
|
119
|
+
static txnid_t txnid;
|
|
120
|
+
static uint64_t sequence;
|
|
121
|
+
static MDBX_canary canary;
|
|
122
|
+
static MDBX_envinfo envinfo;
|
|
123
|
+
|
|
124
|
+
#define PRINT 1
|
|
125
|
+
#define NOHDR 2
|
|
126
|
+
#define GLOBAL 4
|
|
127
|
+
static int mode = GLOBAL;
|
|
128
|
+
|
|
129
|
+
static MDBX_val kbuf, dbuf;
|
|
130
|
+
|
|
131
|
+
#define STRLENOF(s) (sizeof(s) - 1)
|
|
132
|
+
|
|
133
|
+
typedef struct flagbit {
|
|
134
|
+
unsigned bit;
|
|
135
|
+
unsigned len;
|
|
136
|
+
char *name;
|
|
137
|
+
} flagbit;
|
|
138
|
+
|
|
139
|
+
#define S(s) STRLENOF(s), s
|
|
140
|
+
|
|
141
|
+
flagbit dbflags[] = {{MDBX_REVERSEKEY, S("reversekey")}, {MDBX_DUPSORT, S("duplicates")},
|
|
142
|
+
{MDBX_DUPSORT, S("dupsort")}, {MDBX_INTEGERKEY, S("integerkey")},
|
|
143
|
+
{MDBX_DUPFIXED, S("dupfix")}, {MDBX_INTEGERDUP, S("integerdup")},
|
|
144
|
+
{MDBX_REVERSEDUP, S("reversedup")}, {0, 0, nullptr}};
|
|
145
|
+
|
|
146
|
+
static int readhdr(void) {
|
|
147
|
+
/* reset parameters */
|
|
148
|
+
if (subname) {
|
|
149
|
+
free(subname);
|
|
150
|
+
subname = nullptr;
|
|
151
|
+
}
|
|
152
|
+
dbi_flags = 0;
|
|
153
|
+
txnid = 0;
|
|
154
|
+
sequence = 0;
|
|
155
|
+
|
|
156
|
+
while (true) {
|
|
157
|
+
errno = 0;
|
|
158
|
+
if (fgets(dbuf.iov_base, (int)dbuf.iov_len, stdin) == nullptr)
|
|
159
|
+
return errno ? errno : EOF;
|
|
160
|
+
if (user_break)
|
|
161
|
+
return MDBX_EINTR;
|
|
162
|
+
|
|
163
|
+
lineno++;
|
|
164
|
+
uint64_t u64;
|
|
165
|
+
|
|
166
|
+
if (valnum(dbuf.iov_base, "VERSION", &u64)) {
|
|
167
|
+
if (u64 != 3) {
|
|
168
|
+
if (!quiet)
|
|
169
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported value %" PRIu64 " for %s\n", prog, lineno, u64,
|
|
170
|
+
"VERSION");
|
|
171
|
+
exit(EXIT_FAILURE);
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (valnum(dbuf.iov_base, "db_pagesize", &u64)) {
|
|
177
|
+
if (!(mode & GLOBAL) && envinfo.mi_dxb_pagesize != u64) {
|
|
178
|
+
if (!quiet)
|
|
179
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore value %" PRIu64 " for '%s' in non-global context\n", prog,
|
|
180
|
+
lineno, u64, "db_pagesize");
|
|
181
|
+
} else if (u64 < MDBX_MIN_PAGESIZE || u64 > MDBX_MAX_PAGESIZE) {
|
|
182
|
+
if (!quiet)
|
|
183
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore unsupported value %" PRIu64 " for %s\n", prog, lineno, u64,
|
|
184
|
+
"db_pagesize");
|
|
185
|
+
} else
|
|
186
|
+
envinfo.mi_dxb_pagesize = (uint32_t)u64;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
char *str = valstr(dbuf.iov_base, "format");
|
|
191
|
+
if (str) {
|
|
192
|
+
if (strcmp(str, "print") == 0) {
|
|
193
|
+
mode |= PRINT;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (strcmp(str, "bytevalue") == 0) {
|
|
197
|
+
mode &= ~PRINT;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (!quiet)
|
|
201
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported value '%s' for %s\n", prog, lineno, str, "format");
|
|
202
|
+
exit(EXIT_FAILURE);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
str = valstr(dbuf.iov_base, "database");
|
|
206
|
+
if (str) {
|
|
207
|
+
if (*str) {
|
|
208
|
+
free(subname);
|
|
209
|
+
subname = osal_strdup(str);
|
|
210
|
+
if (!subname) {
|
|
211
|
+
if (!quiet)
|
|
212
|
+
perror("strdup()");
|
|
213
|
+
exit(EXIT_FAILURE);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
str = valstr(dbuf.iov_base, "type");
|
|
220
|
+
if (str) {
|
|
221
|
+
if (strcmp(str, "btree") != 0) {
|
|
222
|
+
if (!quiet)
|
|
223
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unsupported value '%s' for %s\n", prog, lineno, str, "type");
|
|
224
|
+
free(subname);
|
|
225
|
+
exit(EXIT_FAILURE);
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (valnum(dbuf.iov_base, "mapaddr", &u64)) {
|
|
231
|
+
if (u64) {
|
|
232
|
+
if (!quiet)
|
|
233
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore unsupported value 0x%" PRIx64 " for %s\n", prog, lineno, u64,
|
|
234
|
+
"mapaddr");
|
|
235
|
+
}
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (valnum(dbuf.iov_base, "mapsize", &u64)) {
|
|
240
|
+
if (!(mode & GLOBAL)) {
|
|
241
|
+
if (!quiet)
|
|
242
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore value %" PRIu64 " for '%s' in non-global context\n", prog,
|
|
243
|
+
lineno, u64, "mapsize");
|
|
244
|
+
} else if (u64 < MIN_MAPSIZE || u64 > MAX_MAPSIZE64) {
|
|
245
|
+
if (!quiet)
|
|
246
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore unsupported value 0x%" PRIx64 " for %s\n", prog, lineno, u64,
|
|
247
|
+
"mapsize");
|
|
248
|
+
} else
|
|
249
|
+
envinfo.mi_mapsize = (size_t)u64;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (valnum(dbuf.iov_base, "maxreaders", &u64)) {
|
|
254
|
+
if (!(mode & GLOBAL)) {
|
|
255
|
+
if (!quiet)
|
|
256
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore value %" PRIu64 " for '%s' in non-global context\n", prog,
|
|
257
|
+
lineno, u64, "maxreaders");
|
|
258
|
+
} else if (u64 < 1 || u64 > MDBX_READERS_LIMIT) {
|
|
259
|
+
if (!quiet)
|
|
260
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore unsupported value 0x%" PRIx64 " for %s\n", prog, lineno, u64,
|
|
261
|
+
"maxreaders");
|
|
262
|
+
} else
|
|
263
|
+
envinfo.mi_maxreaders = (int)u64;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (valnum(dbuf.iov_base, "txnid", &u64)) {
|
|
268
|
+
if (u64 < MIN_TXNID || u64 > MAX_TXNID) {
|
|
269
|
+
if (!quiet)
|
|
270
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": ignore unsupported value 0x%" PRIx64 " for %s\n", prog, lineno, u64,
|
|
271
|
+
"txnid");
|
|
272
|
+
} else
|
|
273
|
+
txnid = u64;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (valnum(dbuf.iov_base, "sequence", &u64)) {
|
|
278
|
+
sequence = u64;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
str = valstr(dbuf.iov_base, "geometry");
|
|
283
|
+
if (str) {
|
|
284
|
+
if (!(mode & GLOBAL)) {
|
|
285
|
+
if (!quiet)
|
|
286
|
+
fprintf(stderr,
|
|
287
|
+
"%s: line %" PRIiSIZE ": ignore values %s"
|
|
288
|
+
" for '%s' in non-global context\n",
|
|
289
|
+
prog, lineno, str, "geometry");
|
|
290
|
+
} else if (sscanf(str, "l%" PRIu64 ",c%" PRIu64 ",u%" PRIu64 ",s%" PRIu64 ",g%" PRIu64, &envinfo.mi_geo.lower,
|
|
291
|
+
&envinfo.mi_geo.current, &envinfo.mi_geo.upper, &envinfo.mi_geo.shrink,
|
|
292
|
+
&envinfo.mi_geo.grow) != 5) {
|
|
293
|
+
if (!quiet)
|
|
294
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected line format for '%s'\n", prog, lineno, "geometry");
|
|
295
|
+
exit(EXIT_FAILURE);
|
|
296
|
+
}
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
str = valstr(dbuf.iov_base, "canary");
|
|
301
|
+
if (str) {
|
|
302
|
+
if (!(mode & GLOBAL)) {
|
|
303
|
+
if (!quiet)
|
|
304
|
+
fprintf(stderr,
|
|
305
|
+
"%s: line %" PRIiSIZE ": ignore values %s"
|
|
306
|
+
" for '%s' in non-global context\n",
|
|
307
|
+
prog, lineno, str, "canary");
|
|
308
|
+
} else if (sscanf(str, "v%" PRIu64 ",x%" PRIu64 ",y%" PRIu64 ",z%" PRIu64, &canary.v, &canary.x, &canary.y,
|
|
309
|
+
&canary.z) != 4) {
|
|
310
|
+
if (!quiet)
|
|
311
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected line format for '%s'\n", prog, lineno, "canary");
|
|
312
|
+
exit(EXIT_FAILURE);
|
|
313
|
+
}
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
for (int i = 0; dbflags[i].bit; i++) {
|
|
318
|
+
bool value = false;
|
|
319
|
+
if (valbool(dbuf.iov_base, dbflags[i].name, &value)) {
|
|
320
|
+
if (value)
|
|
321
|
+
dbi_flags |= dbflags[i].bit;
|
|
322
|
+
else
|
|
323
|
+
dbi_flags &= ~dbflags[i].bit;
|
|
324
|
+
goto next;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
str = valstr(dbuf.iov_base, "HEADER");
|
|
329
|
+
if (str) {
|
|
330
|
+
if (strcmp(str, "END") == 0)
|
|
331
|
+
return MDBX_SUCCESS;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (!quiet)
|
|
335
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unrecognized keyword ignored: %s\n", prog, lineno,
|
|
336
|
+
(char *)dbuf.iov_base);
|
|
337
|
+
next:;
|
|
338
|
+
}
|
|
339
|
+
return EOF;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
static int badend(void) {
|
|
343
|
+
if (!quiet)
|
|
344
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": unexpected end of input\n", prog, lineno);
|
|
345
|
+
return errno ? errno : MDBX_ENODATA;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static inline int unhex(unsigned char *c2) {
|
|
349
|
+
int8_t hi = c2[0];
|
|
350
|
+
hi = (hi | 0x20) - 'a';
|
|
351
|
+
hi += 10 + ((hi >> 7) & 39);
|
|
352
|
+
|
|
353
|
+
int8_t lo = c2[1];
|
|
354
|
+
lo = (lo | 0x20) - 'a';
|
|
355
|
+
lo += 10 + ((lo >> 7) & 39);
|
|
356
|
+
|
|
357
|
+
return hi << 4 | lo;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
__hot static int readline(MDBX_val *out, MDBX_val *buf) {
|
|
361
|
+
unsigned char *c1, *c2, *end;
|
|
362
|
+
size_t len, l2;
|
|
363
|
+
int c;
|
|
364
|
+
|
|
365
|
+
if (user_break)
|
|
366
|
+
return MDBX_EINTR;
|
|
367
|
+
|
|
368
|
+
errno = 0;
|
|
369
|
+
if (!(mode & NOHDR)) {
|
|
370
|
+
c = fgetc(stdin);
|
|
371
|
+
if (c == EOF)
|
|
372
|
+
return errno ? errno : EOF;
|
|
373
|
+
if (c != ' ') {
|
|
374
|
+
lineno++;
|
|
375
|
+
errno = 0;
|
|
376
|
+
if (fgets(buf->iov_base, (int)buf->iov_len, stdin)) {
|
|
377
|
+
if (c == 'D' && !strncmp(buf->iov_base, "ATA=END", STRLENOF("ATA=END")))
|
|
378
|
+
return EOF;
|
|
379
|
+
}
|
|
380
|
+
return badend();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == nullptr)
|
|
384
|
+
return errno ? errno : EOF;
|
|
385
|
+
lineno++;
|
|
386
|
+
|
|
387
|
+
c1 = buf->iov_base;
|
|
388
|
+
len = strlen((char *)c1);
|
|
389
|
+
l2 = len;
|
|
390
|
+
|
|
391
|
+
/* Is buffer too short? */
|
|
392
|
+
while (c1[len - 1] != '\n') {
|
|
393
|
+
buf->iov_base = osal_realloc(buf->iov_base, buf->iov_len * 2);
|
|
394
|
+
if (!buf->iov_base) {
|
|
395
|
+
if (!quiet)
|
|
396
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": out of memory, line too long\n", prog, lineno);
|
|
397
|
+
return MDBX_ENOMEM;
|
|
398
|
+
}
|
|
399
|
+
c1 = buf->iov_base;
|
|
400
|
+
c1 += l2;
|
|
401
|
+
errno = 0;
|
|
402
|
+
if (fgets((char *)c1, (int)buf->iov_len + 1, stdin) == nullptr)
|
|
403
|
+
return errno ? errno : EOF;
|
|
404
|
+
buf->iov_len *= 2;
|
|
405
|
+
len = strlen((char *)c1);
|
|
406
|
+
l2 += len;
|
|
407
|
+
}
|
|
408
|
+
c1 = c2 = buf->iov_base;
|
|
409
|
+
len = l2;
|
|
410
|
+
c1[--len] = '\0';
|
|
411
|
+
end = c1 + len;
|
|
412
|
+
|
|
413
|
+
if (mode & PRINT) {
|
|
414
|
+
while (c2 < end) {
|
|
415
|
+
if (unlikely(*c2 == '\\')) {
|
|
416
|
+
if (c2[1] == '\\') {
|
|
417
|
+
*c1++ = '\\';
|
|
418
|
+
} else {
|
|
419
|
+
if (c2 + 3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2]))
|
|
420
|
+
return badend();
|
|
421
|
+
*c1++ = (char)unhex(++c2);
|
|
422
|
+
}
|
|
423
|
+
c2 += 2;
|
|
424
|
+
} else {
|
|
425
|
+
/* copies are redundant when no escapes were used */
|
|
426
|
+
*c1++ = *c2++;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
/* odd length not allowed */
|
|
431
|
+
if (len & 1)
|
|
432
|
+
return badend();
|
|
433
|
+
while (c2 < end) {
|
|
434
|
+
if (!isxdigit(*c2) || !isxdigit(c2[1]))
|
|
435
|
+
return badend();
|
|
436
|
+
*c1++ = (char)unhex(c2);
|
|
437
|
+
c2 += 2;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
c2 = out->iov_base = buf->iov_base;
|
|
441
|
+
out->iov_len = c1 - c2;
|
|
442
|
+
|
|
443
|
+
return MDBX_SUCCESS;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
static void usage(void) {
|
|
447
|
+
fprintf(stderr,
|
|
448
|
+
"usage: %s "
|
|
449
|
+
"[-V] [-q] [-a] [-f file] [-s name] [-N] [-p] [-T] [-r] [-n] dbpath\n"
|
|
450
|
+
" -V\t\tprint version and exit\n"
|
|
451
|
+
" -q\t\tbe quiet\n"
|
|
452
|
+
" -a\t\tappend records in input order (required for custom "
|
|
453
|
+
"comparators)\n"
|
|
454
|
+
" -f file\tread from file instead of stdin\n"
|
|
455
|
+
" -s name\tload into specified named table\n"
|
|
456
|
+
" -N\t\tdon't overwrite existing records when loading, just skip "
|
|
457
|
+
"ones\n"
|
|
458
|
+
" -p\t\tpurge table before loading\n"
|
|
459
|
+
" -T\t\tread plaintext\n"
|
|
460
|
+
" -r\t\trescue mode (ignore errors to load corrupted DB dump)\n"
|
|
461
|
+
" -n\t\tdon't use subdirectory for newly created database "
|
|
462
|
+
"(MDBX_NOSUBDIR)\n",
|
|
463
|
+
prog);
|
|
464
|
+
exit(EXIT_FAILURE);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
static int equal_or_greater(const MDBX_val *a, const MDBX_val *b) {
|
|
468
|
+
return (a->iov_len == b->iov_len && memcmp(a->iov_base, b->iov_base, a->iov_len) == 0) ? 0 : 1;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
int main(int argc, char *argv[]) {
|
|
472
|
+
int i, err;
|
|
473
|
+
MDBX_env *env = nullptr;
|
|
474
|
+
MDBX_txn *txn = nullptr;
|
|
475
|
+
MDBX_cursor *mc = nullptr;
|
|
476
|
+
MDBX_dbi dbi;
|
|
477
|
+
char *envname = nullptr;
|
|
478
|
+
int envflags = MDBX_SAFE_NOSYNC | MDBX_ACCEDE, putflags = MDBX_UPSERT;
|
|
479
|
+
bool rescue = false;
|
|
480
|
+
bool purge = false;
|
|
481
|
+
|
|
482
|
+
prog = argv[0];
|
|
483
|
+
if (argc < 2)
|
|
484
|
+
usage();
|
|
485
|
+
|
|
486
|
+
while ((i = getopt(argc, argv,
|
|
487
|
+
"a"
|
|
488
|
+
"f:"
|
|
489
|
+
"n"
|
|
490
|
+
"s:"
|
|
491
|
+
"N"
|
|
492
|
+
"p"
|
|
493
|
+
"T"
|
|
494
|
+
"V"
|
|
495
|
+
"r"
|
|
496
|
+
"q")) != EOF) {
|
|
497
|
+
switch (i) {
|
|
498
|
+
case 'V':
|
|
499
|
+
printf("mdbx_load version %d.%d.%d.%d\n"
|
|
500
|
+
" - source: %s %s, commit %s, tree %s\n"
|
|
501
|
+
" - anchor: %s\n"
|
|
502
|
+
" - build: %s for %s by %s\n"
|
|
503
|
+
" - flags: %s\n"
|
|
504
|
+
" - options: %s\n",
|
|
505
|
+
mdbx_version.major, mdbx_version.minor, mdbx_version.patch, mdbx_version.tweak, mdbx_version.git.describe,
|
|
506
|
+
mdbx_version.git.datetime, mdbx_version.git.commit, mdbx_version.git.tree, mdbx_sourcery_anchor,
|
|
507
|
+
mdbx_build.datetime, mdbx_build.target, mdbx_build.compiler, mdbx_build.flags, mdbx_build.options);
|
|
508
|
+
return EXIT_SUCCESS;
|
|
509
|
+
case 'a':
|
|
510
|
+
putflags |= MDBX_APPEND;
|
|
511
|
+
break;
|
|
512
|
+
case 'f':
|
|
513
|
+
if (freopen(optarg, "r", stdin) == nullptr) {
|
|
514
|
+
if (!quiet)
|
|
515
|
+
fprintf(stderr, "%s: %s: open: %s\n", prog, optarg, mdbx_strerror(errno));
|
|
516
|
+
exit(EXIT_FAILURE);
|
|
517
|
+
}
|
|
518
|
+
break;
|
|
519
|
+
case 'n':
|
|
520
|
+
envflags |= MDBX_NOSUBDIR;
|
|
521
|
+
break;
|
|
522
|
+
case 's':
|
|
523
|
+
subname = osal_strdup(optarg);
|
|
524
|
+
break;
|
|
525
|
+
case 'N':
|
|
526
|
+
putflags |= MDBX_NOOVERWRITE | MDBX_NODUPDATA;
|
|
527
|
+
break;
|
|
528
|
+
case 'p':
|
|
529
|
+
purge = true;
|
|
530
|
+
break;
|
|
531
|
+
case 'T':
|
|
532
|
+
mode |= NOHDR | PRINT;
|
|
533
|
+
break;
|
|
534
|
+
case 'q':
|
|
535
|
+
quiet = true;
|
|
536
|
+
break;
|
|
537
|
+
case 'r':
|
|
538
|
+
rescue = true;
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
usage();
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if (optind != argc - 1)
|
|
546
|
+
usage();
|
|
547
|
+
|
|
548
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
549
|
+
SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
|
|
550
|
+
#else
|
|
551
|
+
#ifdef SIGPIPE
|
|
552
|
+
signal(SIGPIPE, signal_handler);
|
|
553
|
+
#endif
|
|
554
|
+
#ifdef SIGHUP
|
|
555
|
+
signal(SIGHUP, signal_handler);
|
|
556
|
+
#endif
|
|
557
|
+
signal(SIGINT, signal_handler);
|
|
558
|
+
signal(SIGTERM, signal_handler);
|
|
559
|
+
#endif /* !WINDOWS */
|
|
560
|
+
|
|
561
|
+
envname = argv[optind];
|
|
562
|
+
if (!quiet) {
|
|
563
|
+
printf("mdbx_load %s (%s, T-%s)\nRunning for %s...\n", mdbx_version.git.describe, mdbx_version.git.datetime,
|
|
564
|
+
mdbx_version.git.tree, envname);
|
|
565
|
+
fflush(nullptr);
|
|
566
|
+
mdbx_setup_debug(MDBX_LOG_NOTICE, MDBX_DBG_DONTCHANGE, logger);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
dbuf.iov_len = 4096;
|
|
570
|
+
dbuf.iov_base = osal_malloc(dbuf.iov_len);
|
|
571
|
+
if (!dbuf.iov_base) {
|
|
572
|
+
err = MDBX_ENOMEM;
|
|
573
|
+
error("value-buffer", err);
|
|
574
|
+
goto bailout;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/* read first header for mapsize= */
|
|
578
|
+
if (!(mode & NOHDR)) {
|
|
579
|
+
err = readhdr();
|
|
580
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
581
|
+
if (err == EOF)
|
|
582
|
+
err = MDBX_ENODATA;
|
|
583
|
+
error("readheader", err);
|
|
584
|
+
goto bailout;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
err = mdbx_env_create(&env);
|
|
589
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
590
|
+
error("mdbx_env_create", err);
|
|
591
|
+
goto bailout;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
err = mdbx_env_set_maxdbs(env, 2);
|
|
595
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
596
|
+
error("mdbx_env_set_maxdbs", err);
|
|
597
|
+
goto bailout;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (envinfo.mi_maxreaders) {
|
|
601
|
+
err = mdbx_env_set_maxreaders(env, envinfo.mi_maxreaders);
|
|
602
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
603
|
+
error("mdbx_env_set_maxreaders", err);
|
|
604
|
+
goto bailout;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (envinfo.mi_geo.current | envinfo.mi_mapsize) {
|
|
609
|
+
if (envinfo.mi_geo.current) {
|
|
610
|
+
err = mdbx_env_set_geometry(env, (intptr_t)envinfo.mi_geo.lower, (intptr_t)envinfo.mi_geo.current,
|
|
611
|
+
(intptr_t)envinfo.mi_geo.upper, (intptr_t)envinfo.mi_geo.shrink,
|
|
612
|
+
(intptr_t)envinfo.mi_geo.grow,
|
|
613
|
+
envinfo.mi_dxb_pagesize ? (intptr_t)envinfo.mi_dxb_pagesize : -1);
|
|
614
|
+
} else {
|
|
615
|
+
if (envinfo.mi_mapsize > MAX_MAPSIZE) {
|
|
616
|
+
if (!quiet)
|
|
617
|
+
fprintf(stderr,
|
|
618
|
+
"Database size is too large for current system (mapsize=%" PRIu64
|
|
619
|
+
" is great than system-limit %zu)\n",
|
|
620
|
+
envinfo.mi_mapsize, (size_t)MAX_MAPSIZE);
|
|
621
|
+
goto bailout;
|
|
622
|
+
}
|
|
623
|
+
err = mdbx_env_set_geometry(env, (intptr_t)envinfo.mi_mapsize, (intptr_t)envinfo.mi_mapsize,
|
|
624
|
+
(intptr_t)envinfo.mi_mapsize, 0, 0,
|
|
625
|
+
envinfo.mi_dxb_pagesize ? (intptr_t)envinfo.mi_dxb_pagesize : -1);
|
|
626
|
+
}
|
|
627
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
628
|
+
error("mdbx_env_set_geometry", err);
|
|
629
|
+
goto bailout;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
err = mdbx_env_open(env, envname, envflags, 0664);
|
|
634
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
635
|
+
error("mdbx_env_open", err);
|
|
636
|
+
goto bailout;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + (size_t)1;
|
|
640
|
+
if (kbuf.iov_len >= INTPTR_MAX / 2) {
|
|
641
|
+
if (!quiet)
|
|
642
|
+
fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n", kbuf.iov_len);
|
|
643
|
+
goto bailout;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
kbuf.iov_base = malloc(kbuf.iov_len);
|
|
647
|
+
if (!kbuf.iov_base) {
|
|
648
|
+
err = MDBX_ENOMEM;
|
|
649
|
+
error("key-buffer", err);
|
|
650
|
+
goto bailout;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
while (err == MDBX_SUCCESS) {
|
|
654
|
+
if (user_break) {
|
|
655
|
+
err = MDBX_EINTR;
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
err = mdbx_txn_begin(env, nullptr, 0, &txn);
|
|
660
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
661
|
+
error("mdbx_txn_begin", err);
|
|
662
|
+
goto bailout;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (mode & GLOBAL) {
|
|
666
|
+
mode -= GLOBAL;
|
|
667
|
+
if (canary.v | canary.x | canary.y | canary.z) {
|
|
668
|
+
err = mdbx_canary_put(txn, &canary);
|
|
669
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
670
|
+
error("mdbx_canary_put", err);
|
|
671
|
+
goto bailout;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const char *const dbi_name = subname ? subname : "@MAIN";
|
|
677
|
+
err = mdbx_dbi_open_ex(txn, subname, dbi_flags | MDBX_CREATE, &dbi,
|
|
678
|
+
(putflags & MDBX_APPEND) ? equal_or_greater : nullptr,
|
|
679
|
+
(putflags & MDBX_APPEND) ? equal_or_greater : nullptr);
|
|
680
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
681
|
+
error("mdbx_dbi_open_ex", err);
|
|
682
|
+
goto bailout;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
uint64_t present_sequence;
|
|
686
|
+
err = mdbx_dbi_sequence(txn, dbi, &present_sequence, 0);
|
|
687
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
688
|
+
error("mdbx_dbi_sequence", err);
|
|
689
|
+
goto bailout;
|
|
690
|
+
}
|
|
691
|
+
if (present_sequence > sequence) {
|
|
692
|
+
if (!quiet)
|
|
693
|
+
fprintf(stderr, "present sequence for '%s' value (%" PRIu64 ") is greater than loaded (%" PRIu64 ")\n",
|
|
694
|
+
dbi_name, present_sequence, sequence);
|
|
695
|
+
err = MDBX_RESULT_TRUE;
|
|
696
|
+
goto bailout;
|
|
697
|
+
}
|
|
698
|
+
if (present_sequence < sequence) {
|
|
699
|
+
err = mdbx_dbi_sequence(txn, dbi, nullptr, sequence - present_sequence);
|
|
700
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
701
|
+
error("mdbx_dbi_sequence", err);
|
|
702
|
+
goto bailout;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (purge) {
|
|
707
|
+
err = mdbx_drop(txn, dbi, false);
|
|
708
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
709
|
+
error("mdbx_drop", err);
|
|
710
|
+
goto bailout;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (putflags & MDBX_APPEND)
|
|
715
|
+
putflags = (dbi_flags & MDBX_DUPSORT) ? putflags | MDBX_APPENDDUP : putflags & ~MDBX_APPENDDUP;
|
|
716
|
+
|
|
717
|
+
err = mdbx_cursor_open(txn, dbi, &mc);
|
|
718
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
719
|
+
error("mdbx_cursor_open", err);
|
|
720
|
+
goto bailout;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
int batch = 0;
|
|
724
|
+
while (err == MDBX_SUCCESS) {
|
|
725
|
+
MDBX_val key, data;
|
|
726
|
+
err = readline(&key, &kbuf);
|
|
727
|
+
if (err == EOF)
|
|
728
|
+
break;
|
|
729
|
+
|
|
730
|
+
if (err == MDBX_SUCCESS)
|
|
731
|
+
err = readline(&data, &dbuf);
|
|
732
|
+
if (err) {
|
|
733
|
+
if (!quiet)
|
|
734
|
+
fprintf(stderr, "%s: line %" PRIiSIZE ": failed to read key value\n", prog, lineno);
|
|
735
|
+
goto bailout;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
err = mdbx_cursor_put(mc, &key, &data, putflags);
|
|
739
|
+
if (err == MDBX_KEYEXIST && putflags)
|
|
740
|
+
continue;
|
|
741
|
+
if (err == MDBX_BAD_VALSIZE && rescue) {
|
|
742
|
+
if (!quiet)
|
|
743
|
+
fprintf(stderr, "%s: skip line %" PRIiSIZE ": due %s\n", prog, lineno, mdbx_strerror(err));
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
747
|
+
error("mdbx_cursor_put", err);
|
|
748
|
+
goto bailout;
|
|
749
|
+
}
|
|
750
|
+
batch++;
|
|
751
|
+
|
|
752
|
+
MDBX_txn_info txn_info;
|
|
753
|
+
err = mdbx_txn_info(txn, &txn_info, false);
|
|
754
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
755
|
+
error("mdbx_txn_info", err);
|
|
756
|
+
goto bailout;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
if (batch == 10000 || txn_info.txn_space_dirty > MEGABYTE * 256) {
|
|
760
|
+
err = mdbx_txn_commit(txn);
|
|
761
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
762
|
+
error("mdbx_txn_commit", err);
|
|
763
|
+
goto bailout;
|
|
764
|
+
}
|
|
765
|
+
batch = 0;
|
|
766
|
+
|
|
767
|
+
err = mdbx_txn_begin(env, nullptr, 0, &txn);
|
|
768
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
769
|
+
error("mdbx_txn_begin", err);
|
|
770
|
+
goto bailout;
|
|
771
|
+
}
|
|
772
|
+
err = mdbx_cursor_bind(txn, mc, dbi);
|
|
773
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
774
|
+
error("mdbx_cursor_bind", err);
|
|
775
|
+
goto bailout;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
mdbx_cursor_close(mc);
|
|
781
|
+
mc = nullptr;
|
|
782
|
+
err = mdbx_txn_commit(txn);
|
|
783
|
+
txn = nullptr;
|
|
784
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
785
|
+
error("mdbx_txn_commit", err);
|
|
786
|
+
goto bailout;
|
|
787
|
+
}
|
|
788
|
+
if (subname) {
|
|
789
|
+
assert(dbi != MAIN_DBI);
|
|
790
|
+
err = mdbx_dbi_close(env, dbi);
|
|
791
|
+
if (unlikely(err != MDBX_SUCCESS)) {
|
|
792
|
+
error("mdbx_dbi_close", err);
|
|
793
|
+
goto bailout;
|
|
794
|
+
}
|
|
795
|
+
} else {
|
|
796
|
+
assert(dbi == MAIN_DBI);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/* try read next header */
|
|
800
|
+
if (!(mode & NOHDR))
|
|
801
|
+
err = readhdr();
|
|
802
|
+
else if (ferror(stdin) || feof(stdin))
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
switch (err) {
|
|
807
|
+
case EOF:
|
|
808
|
+
err = MDBX_SUCCESS;
|
|
809
|
+
case MDBX_SUCCESS:
|
|
810
|
+
break;
|
|
811
|
+
case MDBX_EINTR:
|
|
812
|
+
if (!quiet)
|
|
813
|
+
fprintf(stderr, "Interrupted by signal/user\n");
|
|
814
|
+
break;
|
|
815
|
+
default:
|
|
816
|
+
if (unlikely(err != MDBX_SUCCESS))
|
|
817
|
+
error("readline", err);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
bailout:
|
|
821
|
+
if (mc)
|
|
822
|
+
mdbx_cursor_close(mc);
|
|
823
|
+
if (txn)
|
|
824
|
+
mdbx_txn_abort(txn);
|
|
825
|
+
if (env)
|
|
826
|
+
mdbx_env_close(env);
|
|
827
|
+
free(kbuf.iov_base);
|
|
828
|
+
free(dbuf.iov_base);
|
|
829
|
+
|
|
830
|
+
return err ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
831
|
+
}
|