package com.sleepycat.je.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import com.sleepycat.je.Cursor; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseConfig; import com.sleepycat.je.DatabaseEntry; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.DbInternal; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.JEVersion; import com.sleepycat.je.LockMode; import com.sleepycat.je.OperationStatus; import com.sleepycat.je.config.EnvironmentParams; import com.sleepycat.je.utilint.CmdUtil; import com.sleepycat.je.utilint.DbScavenger; import com.sleepycat.je.utilint.Tracer; import de.ovgu.cide.jakutil.*; public class DbDump { private static final int VERSION=3; protected File envHome=null; protected Environment env; protected String dbName=null; protected boolean formatUsingPrintable; private boolean dupSort; private String outputFileName=null; protected String outputDirectory=null; protected PrintStream outputFile=null; protected boolean doScavengerRun=false; protected boolean doAggressiveScavengerRun=false; protected boolean verbose=false; private static final String usageString="usage: " + CmdUtil.getJavaCommand(DbDump.class) + "\n"+ " -h <dir> # environment home directory\n"+ " [-f <fileName>] # output file, for non -rR dumps\n"+ " [-l] # list databases in the environment\n"+ " [-p] # output printable characters\n"+ " [-r] # salvage mode\n"+ " [-R] # aggressive salvage mode\n"+ " [-d] <directory> # directory for *.dump files (salvage mode)\n"+ " [-s <databaseName>] # database to dump\n"+ " [-v] # verbose in salvage mode\n"+ " [-V] # print JE version number\n"; private DbDump(){ } public DbDump( Environment env, String dbName, PrintStream outputFile, String outputDirectory, boolean formatUsingPrintable){ try { this.envHome=env.getHome(); } catch ( DatabaseException e) { IllegalArgumentException iae=new IllegalArgumentException(); iae.initCause(e); throw iae; } this.env=env; this.dbName=dbName; this.outputFile=outputFile; this.outputDirectory=outputDirectory; this.formatUsingPrintable=formatUsingPrintable; } public static void main( String argv[]) throws DatabaseException, IOException { DbDump dumper=new DbDump(); boolean listDbs=dumper.parseArgs(argv); if (dumper.doScavengerRun) { dumper.openEnv(false); dumper=new DbScavenger(dumper.env,dumper.outputFile,dumper.outputDirectory,dumper.formatUsingPrintable,dumper.doAggressiveScavengerRun,dumper.verbose); ((DbScavenger)dumper).setDumpCorruptedBounds(true); } if (listDbs) { dumper.listDbs(); System.exit(0); } try { dumper.dump(); } catch ( Throwable T) { T.printStackTrace(); } finally { dumper.env.close(); if (dumper.outputFile != null && dumper.outputFile != System.out) { dumper.outputFile.close(); } } } private void listDbs() throws DatabaseException { openEnv(true); List dbNames=env.getDatabaseNames(); Iterator iter=dbNames.iterator(); while (iter.hasNext()) { String name=(String)iter.next(); System.out.println(name); } } protected void printUsage( String msg){ System.err.println(msg); System.err.println(usageString); System.exit(-1); } protected boolean parseArgs( String argv[]) throws IOException { int argc=0; int nArgs=argv.length; boolean listDbs=false; while (argc < nArgs) { String thisArg=argv[argc++]; if (thisArg.equals("-p")) { formatUsingPrintable=true; } else if (thisArg.equals("-V")) { System.out.println(JEVersion.CURRENT_VERSION); System.exit(0); } else if (thisArg.equals("-l")) { listDbs=true; } else if (thisArg.equals("-r")) { doScavengerRun=true; } else if (thisArg.equals("-R")) { doScavengerRun=true; doAggressiveScavengerRun=true; } else if (thisArg.equals("-f")) { if (argc < nArgs) { outputFileName=argv[argc++]; } else { printUsage("-f requires an argument"); } } else if (thisArg.equals("-h")) { if (argc < nArgs) { String envDir=argv[argc++]; envHome=new File(envDir); } else { printUsage("-h requires an argument"); } } else if (thisArg.equals("-d")) { if (argc < nArgs) { outputDirectory=argv[argc++]; } else { printUsage("-d requires an argument"); } } else if (thisArg.equals("-s")) { if (argc < nArgs) { dbName=argv[argc++]; } else { printUsage("-s requires an argument"); } } else if (thisArg.equals("-v")) { verbose=true; } else { printUsage(thisArg + " is not a valid option."); } } if (envHome == null) { printUsage("-h is a required argument"); } if (!listDbs && !doScavengerRun) { if (dbName == null) { printUsage("Must supply a database name if -l not supplied."); } } if (outputFileName == null) { outputFile=System.out; } else { outputFile=new PrintStream(new FileOutputStream(outputFileName)); } return listDbs; } protected void openEnv( boolean doRecovery) throws DatabaseException { if (env == null) { EnvironmentConfig envConfiguration=new EnvironmentConfig(); envConfiguration.setReadOnly(true); envConfiguration.setConfigParam(EnvironmentParams.ENV_RECOVERY.getName(),doRecovery ? "true" : "false"); env=new Environment(envHome,envConfiguration); } } public void dump() throws IOException, DatabaseException { openEnv(true); this.hook834(); DatabaseEntry foundKey=new DatabaseEntry(); DatabaseEntry foundData=new DatabaseEntry(); DatabaseConfig dbConfig=new DatabaseConfig(); dbConfig.setReadOnly(true); DbInternal.setUseExistingConfig(dbConfig,true); Database db=env.openDatabase(null,dbName,dbConfig); dupSort=db.getConfig().getSortedDuplicates(); printHeader(outputFile,dupSort,formatUsingPrintable); Cursor cursor=db.openCursor(null,null); while (cursor.getNext(foundKey,foundData,LockMode.DEFAULT) == OperationStatus.SUCCESS) { dumpOne(outputFile,foundKey.getData(),formatUsingPrintable); dumpOne(outputFile,foundData.getData(),formatUsingPrintable); } cursor.close(); db.close(); outputFile.println("DATA=END"); } protected void printHeader( PrintStream o, boolean dupSort, boolean formatUsingPrintable){ o.println("VERSION=" + VERSION); if (formatUsingPrintable) { o.println("format=print"); } else { o.println("format=bytevalue"); } o.println("type=btree"); o.println("dupsort=" + (dupSort ? "1" : "0")); o.println("HEADER=END"); } protected void dumpOne( PrintStream o, byte[] ba, boolean formatUsingPrintable){ StringBuffer sb=new StringBuffer(); sb.append(' '); CmdUtil.formatEntry(sb,ba,formatUsingPrintable); o.println(sb.toString()); } protected void hook834() throws IOException, DatabaseException { } }