htdb

htdb_dump.cc

Go to the documentation of this file.
00001 //
00002 // NAME
00003 // 
00004 // dump the content of an inverted index in Berkeley DB fashion
00005 //
00006 // SYNOPSIS
00007 //
00008 // htdb_dump [-klNpWz] [-S pagesize] [-C cachesize] [-d ahr] [-f file] [-h home] [-s subdb] db_file
00009 //
00010 // DESCRIPTION
00011 //
00012 // htdb_dump is a slightly modified version of the standard 
00013 // Berkeley DB db_dump utility.
00014 //
00015 // The htdb_dump utility reads the database file <b>db_file</b> and
00016 // writes it to the standard output using a portable flat-text format
00017 // understood by the <i>htdb_load</i>
00018 // utility. The argument <b>db_file</b> must be a file produced using
00019 // the Berkeley DB library functions.
00020 //
00021 // OPTIONS
00022 //
00023 // <dl>
00024 //
00025 // <dt><b>-W</b>
00026 // <dd>Initialize WordContext(3) before dumping. With the <b>-z</b>
00027 // flag allows to dump inverted indexes using the mifluz(3) specific
00028 // compression scheme. The MIFLUZ_CONFIG environment variable must be
00029 // set to a file containing the mifluz(3) configuration.
00030 //
00031 // <dt><b>-z</b>
00032 // <dd>The <b>db_file</b> is compressed. If <b>-W</b> is given the
00033 // mifluz(3) specific compression scheme is used. Otherwise the default
00034 // gzip compression scheme is used.
00035 //
00036 // <dt><b>-d</b>
00037 // <dd>Dump the specified database in a format helpful for debugging
00038 // the Berkeley DB library routines.
00039 // <dl>
00040 // <dt>
00041 // a
00042 // <dd>Display all information.
00043 // <dt>
00044 // h
00045 // <dd>Display only page headers.
00046 // <dt>
00047 // r
00048 // <dd>Do not display the free-list or pages on the free list. This
00049 // mode is used by the recovery tests.
00050 // </dl>
00051 // The output format of the <b>-d</b> option is not standard and may change,
00052 // without notice, between releases of the Berkeley DB library.
00053 //
00054 // <dt><b>-f</b>
00055 // <dd>Write to the specified <b>file</b> instead of to the standard output.
00056 //
00057 // <dt><b>-h</b>
00058 // <dd>Specify a home directory for the database.
00059 // As Berkeley DB versions before 2.0 did not support the concept of a
00060 // <i>database home.</i>
00061 //
00062 // <dt><b>-k</b>
00063 // <dd>Dump record numbers from Queue and Recno databases as keys.
00064 //
00065 // <dt><b>-l</b>
00066 // <dd>List the subdatabases stored in the database.
00067 //
00068 // <dt><b>-N</b>
00069 // <dd>Do not acquire shared region locks while running. Other problems such
00070 // as potentially fatal errors in Berkeley DB will be ignored as well. This option
00071 // is intended only for debugging errors and should not be used under any
00072 // other circumstances.
00073 // 
00074 // <dt><b>-p</b>
00075 // <dd>If characters in either the key or data items are printing characters
00076 // (as defined by <b>isprint</b>(3)), use printing characters in
00077 // <b>file</b> to represent them. This option permits users to use standard
00078 // text editors and tools to modify the contents of databases.
00079 //
00080 // Note, different systems may have different notions as to what characters
00081 // are considered <i>printing characters</i>, and databases dumped in
00082 // this manner may be less portable to external systems.
00083 //
00084 // <dt><b>-s</b>
00085 // <dd>Specify a subdatabase to dump. If no subdatabase is specified, all
00086 // subdatabases found in the database are dumped.
00087 //
00088 // <dt><b>-V</b>
00089 // <dd>Write the version number to the standard output and exit.
00090 //
00091 // </dl>
00092 // 
00093 // Dumping and reloading Hash databases that use user-defined hash functions
00094 // will result in new databases that use the default hash function.
00095 // While using the default hash function may not be optimal for the new database,
00096 // it will continue to work correctly.
00097 //
00098 // Dumping and reloading Btree databases that use user-defined prefix or
00099 // comparison functions will result in new databases that use the default
00100 // prefix and comparison functions.
00101 // <b>In this case, it is quite likely that the database will be damaged
00102 // beyond repair permitting neither record storage or retrieval.</b>
00103 //
00104 // The only available workaround for either case is to modify the sources
00105 // for the <i>htdb_load</i> utility to load the
00106 // database using the correct hash, prefix and comparison functions.
00107 //
00108 // ENVIRONMENT
00109 //
00110 // <b>DB_HOME</b>
00111 // If the <b>-h</b> option is not specified and the environment variable
00112 // DB_HOME is set, it is used as the path of the database home.
00113 // <br>
00114 // <b>MIFLUZ_CONFIG</b>
00115 // file name of configuration file read by WordContext(3). Defaults to
00116 // <b>~/.mifluz.</b> 
00117 //
00118 // AUTHORS
00119 //
00120 // Sleepycat Software http://www.sleepycat.com/
00121 //
00122 //
00123 // END
00124 /*-
00125  * See the file LICENSE for redistribution information.
00126  *
00127  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00128  * Sleepycat Software. All rights reserved.
00129  */
00130 
00131 #ifdef HAVE_CONFIG_H
00132 #include "config.h"
00133 #endif /* HAVE_CONFIG_H */
00134 
00135 #ifndef lint
00136 static const char copyright[] =
00137 "Copyright (c) 1996-2000\nSleepycat Software Inc. All rights reserved.\n";
00138 static const char revid[] =
00139 "$Id: htdb__dump_8cc-source.html,v 1.1 2008年06月08日 10:19:42 sebdiaz Exp $";
00140 #endif
00141 
00142 #ifndef NO_SYSTEM_INCLUDES
00143 #include <sys/types.h>
00144 
00145 #include <errno.h>
00146 #include <stdio.h>
00147 #include <stdlib.h>
00148 #include <string.h>
00149 #include <unistd.h>
00150 #endif
00151 
00152 #ifdef HAVE_GETOPT_H
00153 #include <getopt.h>
00154 #endif /* HAVE_GETOPT_H */
00155 
00156 extern "C" {
00157 #include "db_int.h"
00158 #include "db_page.h"
00159 #include "db_shash.h"
00160 #include "btree.h"
00161 #include "hash.h"
00162 #include "lock.h"
00163 }
00164 
00165 #include "util_sig.h"
00166 
00167 #include "WordContext.h"
00168 #include "WordDBCompress.h"
00169 
00170 void configure __P((char *));
00171 int db_init __P((char *));
00172 int dump __P((DB *, int, int));
00173 int dump_sub __P((DB *, char *, int, int));
00174 int is_sub __P((DB *, int *));
00175 int main __P((int, char *[]));
00176 int show_subs __P((DB *));
00177 void usage __P((void));
00178 static u_int32_t pagesize = 0;
00179 
00180 DB_ENV *dbenv;
00181 const char
00182 *progname = "htdb_dump"; /* Program name. */
00183 
00184 int
00185 main(int argc, char *argv[])
00186 {
00187 extern char *optarg;
00188 extern int optind;
00189 DB *dbp;
00190 int ch, d_close;
00191 int e_close, exitval;
00192 int lflag, pflag, ret, rflag, Rflag, subs, keyflag;
00193 char *dopt, *home, *subname;
00194 int compress = 0;
00195 int wordlist = 0;
00196 u_int32_t cachesize = 0;
00197 WordContext *context = 0;
00198 
00199 dbp = NULL;
00200 d_close = e_close = exitval = lflag = pflag = rflag = Rflag = 0;
00201 keyflag = 0;
00202 dopt = home = subname = NULL;
00203 while ((ch = getopt(argc, argv, "d:f:h:klNprRs:VC:S:zW")) != EOF)
00204 switch (ch) {
00205 case 'd':
00206 dopt = optarg;
00207 break;
00208 case 'f':
00209 if (freopen(optarg, "w", stdout) == NULL) {
00210 fprintf(stderr, "%s: %s: reopen: %s\n",
00211 progname, optarg, strerror(errno));
00212 exit (1);
00213 }
00214 break;
00215 case 'h':
00216 home = optarg;
00217 break;
00218 case 'k':
00219 keyflag = 1;
00220 break;
00221 case 'l':
00222 lflag = 1;
00223 break;
00224 case 'N':
00225 if ((ret = CDB_db_env_set_mutexlocks(0)) != 0) {
00226 fprintf(stderr,
00227 "%s: db_env_set_mutexlocks: %s\n",
00228 progname, CDB_db_strerror(ret));
00229 return (1);
00230 }
00231 if ((ret = CDB_db_env_set_panicstate(0)) != 0) {
00232 fprintf(stderr,
00233 "%s: db_env_set_panicstate: %s\n",
00234 progname, CDB_db_strerror(ret));
00235 return (1);
00236 }
00237 break;
00238 case 'p':
00239 pflag = 1;
00240 break;
00241 case 's':
00242 subname = optarg;
00243 break;
00244 case 'R':
00245 Rflag = 1;
00246 /* DB_AGGRESSIVE requires DB_SALVAGE */
00247 /* FALLTHROUGH */
00248 case 'r':
00249 rflag = 1;
00250 break;
00251 case 'V':
00252 printf("%s\n", CDB_db_version(NULL, NULL, NULL));
00253 exit(0);
00254 case 'C':
00255 cachesize = atoi(optarg);
00256 break;
00257 case 'S':
00258 pagesize = atoi(optarg);
00259 break;
00260 case 'z':
00261 compress = DB_COMPRESS;
00262 break;
00263 case 'W':
00264 wordlist = 1;
00265 break;
00266 case '?':
00267 default:
00268 usage();
00269 }
00270 argc -= optind;
00271 argv += optind;
00272 
00273 if (argc != 1)
00274 usage();
00275 
00276 if (dopt != NULL && pflag) {
00277 fprintf(stderr,
00278 "%s: the -d and -p options may not both be specified\n",
00279 progname);
00280 exit (1);
00281 }
00282 if (lflag && subname != NULL) {
00283 fprintf(stderr,
00284 "%s: the -l and -s options may not both be specified\n",
00285 progname);
00286 exit (1);
00287 }
00288 
00289 if (keyflag && rflag) {
00290 fprintf(stderr, "%s: %s",
00291 "the -k and -r or -R options may not both be specified\n",
00292 progname);
00293 exit(1);
00294 }
00295 
00296 if (subname != NULL && rflag) {
00297 fprintf(stderr, "%s: %s",
00298 "the -s and -r or R options may not both be specified\n",
00299 progname);
00300 exit(1);
00301 }
00302 
00303 /* Handle possible interruptions. */
00304 __db_util_siginit();
00305 
00306 
00307 if(wordlist && compress) {
00308 static ConfigDefaults defaults[] = {
00309 { "wordlist_wordkey_description", "Word 24/DocID 32/Flag 8/Location 16"},
00310 { "wordlist_env_skip", "true"},
00311 { 0, 0, 0 }
00312 };
00313 context = new WordContext(defaults);
00314 }
00315 /*
00316  * Create an environment object and initialize it for error
00317  * reporting.
00318  */
00319 if ((ret = CDB_db_env_create(&dbenv, 0)) != 0) {
00320 fprintf(stderr,
00321 "%s: CDB_db_env_create: %s\n", progname, CDB_db_strerror(ret));
00322 goto err;
00323 }
00324 e_close = 1;
00325 
00326 dbenv->set_errfile(dbenv, stderr);
00327 dbenv->set_errpfx(dbenv, progname);
00328 if(compress && wordlist) dbenv->mp_cmpr_info = (new WordDBCompress(context))->CmprInfo();
00329 
00330 /* Initialize the environment. */
00331 if (db_init(home) != 0)
00332 goto err;
00333 
00334 /* Create the DB object and open the file. */
00335 if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0) {
00336 dbenv->err(dbenv, ret, "CDB_db_create");
00337 goto err;
00338 }
00339 if(cachesize > 0) dbp->set_cachesize(dbp, 0, cachesize, 1);
00340 if(pagesize > 0) dbp->set_pagesize(dbp, pagesize);
00341 d_close = 1;
00342 
00343 /*
00344  * If we're salvaging, don't do an open; it might not be safe.
00345  * Dispatch now into the salvager.
00346  */
00347 if (rflag) {
00348 if ((ret = dbp->verify(dbp, argv[0], NULL, stdout,
00349 DB_SALVAGE | (Rflag ? DB_AGGRESSIVE : 0))) != 0)
00350 goto err;
00351 exitval = 0;
00352 goto done;
00353 }
00354 
00355 if ((ret = dbp->open(dbp,
00356 argv[0], subname, DB_UNKNOWN, (DB_RDONLY | compress), 0)) != 0) {
00357 dbp->err(dbp, ret, "open: %s", argv[0]);
00358 goto err;
00359 }
00360 
00361 if (dopt != NULL) {
00362 if (CDB___db_dump(dbp, dopt, NULL)) {
00363 dbp->err(dbp, ret, "CDB___db_dump: %s", argv[0]);
00364 goto err;
00365 }
00366 } else if (lflag) {
00367 if (is_sub(dbp, &subs))
00368 goto err;
00369 if (subs == 0) {
00370 dbp->errx(dbp,
00371 "%s: does not contain multiple databases", argv[0]);
00372 goto err;
00373 }
00374 if (show_subs(dbp))
00375 goto err;
00376 } else {
00377 subs = 0;
00378 if (subname == NULL && is_sub(dbp, &subs))
00379 goto err;
00380 if (subs) {
00381 if (dump_sub(dbp, argv[0], pflag, keyflag))
00382 goto err;
00383 } else
00384 if (CDB___db_prheader(dbp, NULL, pflag, keyflag, stdout,
00385 CDB___db_verify_callback, NULL, 0) ||
00386 dump(dbp, pflag, keyflag))
00387 goto err;
00388 }
00389 
00390 if (0) {
00391 err: exitval = 1;
00392 }
00393 done: if (d_close && (ret = dbp->close(dbp, 0)) != 0) {
00394 exitval = 1;
00395 dbp->err(dbp, ret, "close");
00396 }
00397 if(wordlist && compress) {
00398 delete (WordDBCompress*)dbenv->mp_cmpr_info->user_data;
00399 delete dbenv->mp_cmpr_info;
00400 }
00401 if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) {
00402 exitval = 1;
00403 fprintf(stderr,
00404 "%s: dbenv->close: %s\n", progname, CDB_db_strerror(ret));
00405 }
00406 
00407 if(context) delete context;
00408 
00409 /* Resend any caught signal. */
00410 __db_util_sigresend();
00411 
00412 return (exitval);
00413 }
00414 
00415 /*
00416  * db_init --
00417  * Initialize the environment.
00418  */
00419 int
00420 db_init(char *home)
00421 {
00422 u_int32_t flags;
00423 int ret;
00424 
00425 /*
00426  * Try and use the shared memory pool region when dumping a database,
00427  * so our information is as up-to-date as possible, even if the mpool
00428  * cache hasn't been flushed.
00429  */
00430 flags = DB_USE_ENVIRON | DB_INIT_MPOOL | DB_INIT_LOCK;
00431 if (dbenv->open(dbenv, home, flags, 0) == 0)
00432 return (0);
00433 
00434 /*
00435  * An environment is required because we may be trying to look at
00436  * databases in directories other than the current one. We could
00437  * avoid using an environment iff the -h option wasn't specified,
00438  * but that seems like more work than it's worth.
00439  *
00440  * No environment exists (or, at least no environment that includes
00441  * an mpool region exists). Create one, but make it private so that
00442  * no files are actually created.
00443  */
00444 LF_SET(DB_CREATE | DB_PRIVATE);
00445 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
00446 return (0);
00447 
00448 /* An environment is required. */
00449 dbenv->err(dbenv, ret, "open");
00450 return (1);
00451 }
00452 
00453 /*
00454  * is_sub --
00455  * Return if the database contains subdatabases.
00456  */
00457 int
00458 is_sub(DB *dbp, int *yesno)
00459 {
00460 DB_BTREE_STAT *btsp = 0;
00461 DB_HASH_STAT *hsp = 0;
00462 int ret;
00463 
00464 switch (dbp->type) {
00465 case DB_BTREE:
00466 case DB_RECNO:
00467 if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) {
00468 dbp->err(dbp, ret, "DB->stat");
00469 return (ret);
00470 }
00471 *yesno = btsp->bt_metaflags & BTM_SUBDB ? 1 : 0;
00472 break;
00473 case DB_HASH:
00474 if ((ret = dbp->stat(dbp, &hsp, NULL, 0)) != 0) {
00475 dbp->err(dbp, ret, "DB->stat");
00476 return (ret);
00477 }
00478 *yesno = hsp->hash_metaflags & DB_HASH_SUBDB ? 1 : 0;
00479 break;
00480 case DB_QUEUE:
00481 break;
00482 default:
00483 dbp->errx(dbp, "unknown database type");
00484 return (1);
00485 }
00486 if(btsp) free(btsp);
00487 if(hsp) free(hsp);
00488 return (0);
00489 }
00490 
00491 /*
00492  * dump_sub --
00493  * Dump out the records for a DB containing subdatabases.
00494  */
00495 int
00496 dump_sub(DB *parent_dbp, char *parent_name, int pflag, int keyflag)
00497 {
00498 DB *dbp;
00499 DBC *dbcp;
00500 DBT key, data;
00501 int ret;
00502 char *subdb;
00503 
00504 /*
00505  * Get a cursor and step through the database, dumping out each
00506  * subdatabase.
00507  */
00508 if ((ret = parent_dbp->cursor(parent_dbp, NULL, &dbcp, 0)) != 0) {
00509 dbenv->err(dbenv, ret, "DB->cursor");
00510 return (1);
00511 }
00512 
00513 memset(&key, 0, sizeof(key));
00514 memset(&data, 0, sizeof(data));
00515 while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
00516 /* Nul terminate the subdatabase name. */
00517 if ((subdb = (char*)malloc(key.size + 1)) == NULL) {
00518 dbenv->err(dbenv, ENOMEM, NULL);
00519 return (1);
00520 }
00521 memcpy(subdb, key.data, key.size);
00522 subdb[key.size] = '0円';
00523 
00524 /* Create the DB object and open the file. */
00525 if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0) {
00526 dbenv->err(dbenv, ret, "CDB_db_create");
00527 free(subdb);
00528 return (1);
00529 }
00530 if(pagesize > 0) dbp->set_pagesize(dbp, pagesize);
00531 if ((ret = dbp->open(dbp,
00532 parent_name, subdb, DB_UNKNOWN, (DB_RDONLY | ((parent_dbp->flags & DB_AM_CMPR) ? DB_COMPRESS : 0)), 0)) != 0)
00533 dbp->err(dbp, ret,
00534 "DB->open: %s:%s", parent_name, subdb);
00535 if (ret == 0 &&
00536 (CDB___db_prheader(dbp, subdb, pflag, keyflag, stdout,
00537 CDB___db_verify_callback, NULL, 0) ||
00538 dump(dbp, pflag, keyflag)))
00539 ret = 1;
00540 (void)dbp->close(dbp, 0);
00541 free(subdb);
00542 if (ret != 0)
00543 return (1);
00544 }
00545 if (ret != DB_NOTFOUND) {
00546 dbp->err(dbp, ret, "DBcursor->get");
00547 return (1);
00548 }
00549 
00550 if ((ret = dbcp->c_close(dbcp)) != 0) {
00551 dbp->err(dbp, ret, "DBcursor->close");
00552 return (1);
00553 }
00554 
00555 return (0);
00556 }
00557 
00558 /*
00559  * show_subs --
00560  * Display the subdatabases for a database.
00561  */
00562 int
00563 show_subs(DB *dbp)
00564 {
00565 DBC *dbcp;
00566 DBT key, data;
00567 int ret;
00568 
00569 /*
00570  * Get a cursor and step through the database, printing out the key
00571  * of each key/data pair.
00572  */
00573 if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
00574 dbp->err(dbp, ret, "DB->cursor");
00575 return (1);
00576 }
00577 
00578 memset(&key, 0, sizeof(key));
00579 memset(&data, 0, sizeof(data));
00580 while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
00581 if ((ret = CDB___db_prdbt(&key, 1, NULL, stdout,
00582 CDB___db_verify_callback, 0, NULL)) != 0) {
00583 dbp->errx(dbp, NULL);
00584 return (1);
00585 }
00586 }
00587 if (ret != DB_NOTFOUND) {
00588 dbp->err(dbp, ret, "DBcursor->get");
00589 return (1);
00590 }
00591 
00592 if ((ret = dbcp->c_close(dbcp)) != 0) {
00593 dbp->err(dbp, ret, "DBcursor->close");
00594 return (1);
00595 }
00596 return (0);
00597 }
00598 
00599 /*
00600  * dump --
00601  * Dump out the records for a DB.
00602  */
00603 int
00604 dump(DB *dbp, int pflag, int keyflag)
00605 {
00606 DBC *dbcp;
00607 DBT key, data;
00608 int ret, is_recno;
00609 
00610 /*
00611  * Get a cursor and step through the database, printing out each
00612  * key/data pair.
00613  */
00614 if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
00615 dbp->err(dbp, ret, "DB->cursor");
00616 return (1);
00617 }
00618 
00619 memset(&key, 0, sizeof(key));
00620 memset(&data, 0, sizeof(data));
00621 is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE);
00622 keyflag = is_recno ? keyflag : 1;
00623 while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
00624 if ((keyflag && (ret = CDB___db_prdbt(&key,
00625 pflag, " ", stdout, CDB___db_verify_callback,
00626 is_recno, NULL)) != 0) || (ret =
00627 CDB___db_prdbt(&data, pflag, " ", stdout,
00628 CDB___db_verify_callback, 0, NULL)) != 0) {
00629 dbp->errx(dbp, NULL);
00630 return (1);
00631 }
00632 if (ret != DB_NOTFOUND) {
00633 dbp->err(dbp, ret, "DBcursor->get");
00634 return (1);
00635 }
00636 
00637 if ((ret = dbcp->c_close(dbcp)) != 0) {
00638 dbp->err(dbp, ret, "DBcursor->close");
00639 return (1);
00640 }
00641 
00642 (void)CDB___db_prfooter(stdout, CDB___db_verify_callback);
00643 return (0);
00644 }
00645 
00646 /*
00647  * usage --
00648  * Display the usage message.
00649  */
00650 void
00651 usage()
00652 {
00653 (void)fprintf(stderr, "usage: %s\n",
00654 "htdb_dump [-klNprRVWz] [-S pagesize] [-C cachesize] [-d ahr] [-f output] [-h home] [-s database] db_file\n");
00655 exit(1);
00656 }

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /