NCBI C++ ToolKit
mdb_dump.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* mdb_dump.c - memory-mapped database dump tool */
2 /*
3  * Copyright 2011-2018 Howard Chu, Symas Corp.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted only as authorized by the OpenLDAP
8  * Public License.
9  *
10  * A copy of this license is available in the file LICENSE in the
11  * top-level directory of the distribution or, alternatively, at
12  * <http://www.OpenLDAP.org/license.html>.
13  */
14 #include <stdio.h>
15 #include <errno.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <unistd.h>
20 #include <signal.h>
21 #include "lmdb.h"
22 
23 #ifdef _WIN32
24 #define Z "I"
25 #else
26 #define Z "z"
27 #endif
28 
29 #define PRINT 1
30 static int mode;
31 
32 typedef struct flagbit {
33  int bit;
34  char *name;
36 
38  { MDB_REVERSEKEY, "reversekey" },
39  { MDB_DUPSORT, "dupsort" },
40  { MDB_INTEGERKEY, "integerkey" },
41  { MDB_DUPFIXED, "dupfixed" },
42  { MDB_INTEGERDUP, "integerdup" },
43  { MDB_REVERSEDUP, "reversedup" },
44  { 0, NULL }
45 };
46 
47 static volatile sig_atomic_t gotsig;
48 
49 static void dumpsig( int sig )
50 {
51  gotsig=1;
52 }
53 
54 static const char hexc[] = "0123456789abcdef";
55 
56 static void hex(unsigned char c)
57 {
58  putchar(hexc[c >> 4]);
59  putchar(hexc[c & 0xf]);
60 }
61 
62 static void text(MDB_val *v)
63 {
64  unsigned char *c, *end;
65 
66  putchar(' ');
67  c = v->mv_data;
68  end = c + v->mv_size;
69  while (c < end) {
70  if (isprint(*c)) {
71  putchar(*c);
72  } else {
73  putchar('\\');
74  hex(*c);
75  }
76  c++;
77  }
78  putchar('\n');
79 }
80 
81 static void byte(MDB_val *v)
82 {
83  unsigned char *c, *end;
84 
85  putchar(' ');
86  c = v->mv_data;
87  end = c + v->mv_size;
88  while (c < end) {
89  hex(*c++);
90  }
91  putchar('\n');
92 }
93 
94 /* Dump in BDB-compatible format */
95 static int dumpit(MDB_txn *txn, MDB_dbi dbi, char *name)
96 {
97  MDB_cursor *mc;
98  MDB_stat ms;
99  MDB_val key, data;
101  unsigned int flags;
102  int rc, i;
103 
104  rc = mdb_dbi_flags(txn, dbi, &flags);
105  if (rc) return rc;
106 
107  rc = mdb_stat(txn, dbi, &ms);
108  if (rc) return rc;
109 
110  rc = mdb_env_info(mdb_txn_env(txn), &info);
111  if (rc) return rc;
112 
113  printf("VERSION=3\n");
114  printf("format=%s\n", mode & PRINT ? "print" : "bytevalue");
115  if (name)
116  printf("database=%s\n", name);
117  printf("type=btree\n");
118  printf("mapsize=%" Z "u\n", info.me_mapsize);
119  if (info.me_mapaddr)
120  printf("mapaddr=%p\n", info.me_mapaddr);
121  printf("maxreaders=%u\n", info.me_maxreaders);
122 
123  if (flags & MDB_DUPSORT)
124  printf("duplicates=1\n");
125 
126  for (i=0; dbflags[i].bit; i++)
127  if (flags & dbflags[i].bit)
128  printf("%s=1\n", dbflags[i].name);
129 
130  printf("db_pagesize=%d\n", ms.ms_psize);
131  printf("HEADER=END\n");
132 
133  rc = mdb_cursor_open(txn, dbi, &mc);
134  if (rc) return rc;
135 
136  while ((rc = mdb_cursor_get(mc, &key, &data, MDB_NEXT) == MDB_SUCCESS)) {
137  if (gotsig) {
138  rc = EINTR;
139  break;
140  }
141  if (mode & PRINT) {
142  text(&key);
143  text(&data);
144  } else {
145  byte(&key);
146  byte(&data);
147  }
148  }
149  printf("DATA=END\n");
150  if (rc == MDB_NOTFOUND)
151  rc = MDB_SUCCESS;
152 
153  return rc;
154 }
155 
156 static void usage(char *prog)
157 {
158  fprintf(stderr, "usage: %s [-V] [-f output] [-l] [-n] [-p] [-a|-s subdb] dbpath\n", prog);
160 }
161 
162 int main(int argc, char *argv[])
163 {
164  int i, rc;
165  MDB_env *env;
166  MDB_txn *txn;
167  MDB_dbi dbi;
168  char *prog = argv[0];
169  char *envname;
170  char *subname = NULL;
171  int alldbs = 0, envflags = 0, list = 0;
172 
173  if (argc < 2) {
174  usage(prog);
175  }
176 
177  /* -a: dump main DB and all subDBs
178  * -s: dump only the named subDB
179  * -n: use NOSUBDIR flag on env_open
180  * -p: use printable characters
181  * -f: write to file instead of stdout
182  * -V: print version and exit
183  * (default) dump only the main DB
184  */
185  while ((i = getopt(argc, argv, "af:lnps:V")) != EOF) {
186  switch(i) {
187  case 'V':
188  printf("%s\n", MDB_VERSION_STRING);
189  exit(0);
190  break;
191  case 'l':
192  list = 1;
193  /*FALLTHROUGH*/;
194  case 'a':
195  if (subname)
196  usage(prog);
197  alldbs++;
198  break;
199  case 'f':
200  if (freopen(optarg, "w", stdout) == NULL) {
201  fprintf(stderr, "%s: %s: reopen: %s\n",
202  prog, optarg, strerror(errno));
204  }
205  break;
206  case 'n':
207  envflags |= MDB_NOSUBDIR;
208  break;
209  case 'p':
210  mode |= PRINT;
211  break;
212  case 's':
213  if (alldbs)
214  usage(prog);
215  subname = optarg;
216  break;
217  default:
218  usage(prog);
219  }
220  }
221 
222  if (optind != argc - 1)
223  usage(prog);
224 
225 #ifdef SIGPIPE
226  signal(SIGPIPE, dumpsig);
227 #endif
228 #ifdef SIGHUP
229  signal(SIGHUP, dumpsig);
230 #endif
231  signal(SIGINT, dumpsig);
232  signal(SIGTERM, dumpsig);
233 
234  envname = argv[optind];
235  rc = mdb_env_create(&env);
236  if (rc) {
237  fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
238  return EXIT_FAILURE;
239  }
240 
241  if (alldbs || subname) {
243  }
244 
245  rc = mdb_env_open(env, envname, envflags | MDB_RDONLY, 0664);
246  if (rc) {
247  fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
248  goto env_close;
249  }
250 
251  rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
252  if (rc) {
253  fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
254  goto env_close;
255  }
256 
257  rc = mdb_open(txn, subname, 0, &dbi);
258  if (rc) {
259  fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
260  goto txn_abort;
261  }
262 
263  if (alldbs) {
264  MDB_cursor *cursor;
265  MDB_val key;
266  int count = 0;
267 
268  rc = mdb_cursor_open(txn, dbi, &cursor);
269  if (rc) {
270  fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
271  goto txn_abort;
272  }
273  while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT_NODUP)) == 0) {
274  char *str;
275  MDB_dbi db2;
276  if (memchr(key.mv_data, '\0', key.mv_size))
277  continue;
278  count++;
279  str = malloc(key.mv_size+1);
280  memcpy(str, key.mv_data, key.mv_size);
281  str[key.mv_size] = '\0';
282  rc = mdb_open(txn, str, 0, &db2);
283  if (rc == MDB_SUCCESS) {
284  if (list) {
285  printf("%s\n", str);
286  list++;
287  } else {
288  rc = dumpit(txn, db2, str);
289  if (rc)
290  break;
291  }
292  mdb_close(env, db2);
293  }
294  free(str);
295  if (rc) continue;
296  }
297  mdb_cursor_close(cursor);
298  if (!count) {
299  fprintf(stderr, "%s: %s does not contain multiple databases\n", prog, envname);
300  rc = MDB_NOTFOUND;
301  } else if (rc == MDB_NOTFOUND) {
302  rc = MDB_SUCCESS;
303  }
304  } else {
305  rc = dumpit(txn, dbi, subname);
306  }
307  if (rc && rc != MDB_NOTFOUND)
308  fprintf(stderr, "%s: %s: %s\n", prog, envname, mdb_strerror(rc));
309 
310  mdb_close(env, dbi);
311 txn_abort:
312  mdb_txn_abort(txn);
313 env_close:
315 
316  return rc ? EXIT_FAILURE : EXIT_SUCCESS;
317 }
static uch flags
#define EXIT_SUCCESS
Definition: common.h:39
#define EXIT_FAILURE
Definition: fastme.h:73
static const char * str(char *buf, int n)
Definition: stats.c:84
static HENV env
Definition: transaction2.c:38
#define getopt
Definition: replacements.h:157
#define optarg
#define optind
char data[12]
Definition: iconv.c:80
#define NULL
Definition: ncbistd.hpp:225
#define MDB_VERSION_STRING
The full library version as a C string.
Definition: lmdb.h:222
#define MDB_NOTFOUND
key/data pair not found (EOF)
Definition: lmdb.h:407
#define MDB_SUCCESS
Successful result.
Definition: lmdb.h:403
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
Definition: mdb.c:9689
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
Definition: mdb.c:4959
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
Definition: mdb.c:5156
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Definition: mdb.c:6319
void mdb_txn_abort(MDB_txn *txn)
Abandon all the operations of the transaction instead of saving them.
Definition: mdb.c:3061
int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Retrieve the DB flags for a database handle.
Definition: mdb.c:9883
char * mdb_strerror(int err)
Return a string describing a given error code.
Definition: mdb.c:1479
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Create a cursor handle.
Definition: mdb.c:7634
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
Definition: mdb.c:4094
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
Definition: mdb.c:3951
#define mdb_open(txn, name, flags, dbi)
Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project.
Definition: lmdb.h:1056
#define mdb_close(env, dbi)
Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project.
Definition: lmdb.h:1058
void mdb_cursor_close(MDB_cursor *cursor)
Close a cursor handle.
Definition: mdb.c:7723
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
Definition: mdb.c:2829
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
Definition: mdb.c:9850
MDB_env * mdb_txn_env(MDB_txn *txn)
Returns the transaction's MDB_env.
Definition: mdb.c:2930
@ MDB_NEXT_NODUP
Position at first data item of next key.
Definition: lmdb.h:385
@ MDB_NEXT
Position at next data item.
Definition: lmdb.h:379
#define MDB_INTEGERKEY
numeric keys in native byte order: either unsigned int or size_t.
Definition: lmdb.h:317
#define MDB_DUPFIXED
with MDB_DUPSORT, sorted dup items have fixed size
Definition: lmdb.h:319
#define MDB_INTEGERDUP
with MDB_DUPSORT, dups are MDB_INTEGERKEY-style integers
Definition: lmdb.h:321
#define MDB_DUPSORT
use sorted duplicates
Definition: lmdb.h:314
#define MDB_REVERSEKEY
use reverse string keys
Definition: lmdb.h:312
#define MDB_REVERSEDUP
with MDB_DUPSORT, use reverse string dups
Definition: lmdb.h:323
#define MDB_NOSUBDIR
no environment directory
Definition: lmdb.h:287
#define MDB_RDONLY
read only
Definition: lmdb.h:291
unsigned int me_maxreaders
max reader slots in the environment
Definition: lmdb.h:472
size_t me_mapsize
Size of the data memory map.
Definition: lmdb.h:469
void * me_mapaddr
Address of map, if fixed.
Definition: lmdb.h:468
size_t mv_size
size of the data item
Definition: lmdb.h:258
void * mv_data
address of the data item
Definition: lmdb.h:259
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition: lmdb.h:241
exit(2)
int i
int main(int argc, char *argv[])
Definition: mdb_dump.c:162
static int mode
Definition: mdb_dump.c:30
static void hex(unsigned char c)
Definition: mdb_dump.c:56
flagbit dbflags[]
Definition: mdb_dump.c:37
#define Z
Definition: mdb_dump.c:26
static volatile sig_atomic_t gotsig
Definition: mdb_dump.c:47
static void byte(MDB_val *v)
Definition: mdb_dump.c:81
#define PRINT
Definition: mdb_dump.c:29
static void usage(char *prog)
Definition: mdb_dump.c:156
static void dumpsig(int sig)
Definition: mdb_dump.c:49
struct flagbit flagbit
static const char hexc[]
Definition: mdb_dump.c:54
static int dumpit(MDB_txn *txn, MDB_dbi dbi, char *name)
Definition: mdb_dump.c:95
static void text(MDB_val *v)
Definition: mdb_dump.c:62
static MDB_envinfo info
Definition: mdb_load.c:37
static char * prog
Definition: mdb_load.c:33
static char * subname
Definition: mdb_load.c:26
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:381
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:594
const struct ncbi::grid::netcache::search::fields::KEY key
int isprint(Uchar c)
Definition: ncbictype.hpp:67
char * strerror(int n)
Definition: pcre2grep.c:1177
#define count
static SLJIT_INLINE sljit_ins ms(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
Cursors are used for all DB operations.
Definition: mdb.c:1184
The database environment.
Definition: mdb.c:1259
Information about the environment.
Definition: lmdb.h:467
Statistics for a database in the environment.
Definition: lmdb.h:456
A database transaction.
Definition: mdb.c:1084
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:257
int bit
Definition: mdb_dump.c:33
char * name
Definition: mdb_dump.c:34
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Sep 20 14:58:28 2024 by modify_doxy.py rev. 669887