/* * Copyright (c) 2009-2010, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist, * Felix Hupfeld, Felix Langner, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package de.mxro.thrd.babudb05.tools; import java.io.PrintStream; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import de.mxro.thrd.babudb05.BabuDBFactory; import de.mxro.thrd.babudb05.api.BabuDB; import de.mxro.thrd.babudb05.api.database.Database; import de.mxro.thrd.babudb05.api.exception.BabuDBException; import de.mxro.thrd.babudb05.config.ConfigBuilder; import de.mxro.thrd.xstreemfs.foundation.util.OutputUtils; /** * A tool that creates a complete dump of a database. * * @author stenjan * */ public class DBDumpTool { /** * Generates string representations out of byte arrays. * * @author stenjan * */ public interface RecordFormatter { /** * Formats a specific key stored in a database. * * @param key * the key * @return a formatted string representation of the key */ public String formatKey(byte[] key, String databaseName, int indexId); /** * Formats a specific key stored in a database. * * @param key * the key * @return a formatted string representation of the key */ public String formatValue(byte[] value, byte[] key, String databaseName, int indexId); } /** * Creates an XML dump of a database. * * @param dbDir * the database directory * @param logDir * the database log directory * @param compression * if compression is enabled * @param formatter * the record formatter. The formatter has to ensure that all * returned strings are XML-compliant, which implies that * non-printable and XML characters have to be escaped according * to the rules of well-formed XML documents. * @param out * the stream to which the dump is written * @throws BabuDBException * if an error occurs while dumping the database */ public static void dumpDB(String dbDir, String logDir, boolean compression, RecordFormatter formatter, PrintStream out) throws BabuDBException { BabuDB databaseSystem = BabuDBFactory.createBabuDB(new ConfigBuilder().setDataPath(dbDir, logDir) .setCompressed(compression).build()); out.println("<BabuDB version=\"" + BabuDBFactory.BABUDB_VERSION + "\">"); Map<String, Database> dbs = databaseSystem.getDatabaseManager().getDatabases(); long entryCount = 0; for (Entry<String, Database> entry : dbs.entrySet()) { Database db = entry.getValue(); out.println("\t<database name=\"" + db.getName() + "\">"); int numIndices = db.getComparators().length; for (int i = 0; i < numIndices; i++) { out.println("\t\t<index number=\"" + i + "\">"); Iterator<Entry<byte[], byte[]>> it = db.prefixLookup(i, new byte[0], null).get(); while (it.hasNext()) { Entry<byte[], byte[]> next = it.next(); out.println("\t\t\t<key>"); out.println("\t\t\t\t" + formatter.formatKey(next.getKey(), db.getName(), i)); out.println("\t\t\t</key>"); out.println("\t\t\t<value>"); out.println("\t\t\t\t" + formatter.formatValue(next.getValue(), next.getKey(), db.getName(), i)); out.println("\t\t\t</value>"); entryCount++; } out.println("\t\t</index>"); } out.println("\t</database>"); } out.println("</BabuDB>"); databaseSystem.shutdown(); } public static void main(String[] args) throws Exception { if (args.length < 2 || args.length > 3) { System.out.println("usage: " + DBDumpTool.class.getSimpleName() + " <DB directory> <DB log directory> [dump file]"); return; } final String dbDir = args[0]; final String logDir = args[1]; final PrintStream out = args.length == 3 ? new PrintStream(args[2]) : System.out; final RecordFormatter formatter = new RecordFormatter() { public String formatValue(byte[] value, byte[] key, String databaseName, int indexId) { return OutputUtils.byteArrayToHexString(value); } public String formatKey(byte[] key, String databaseName, int indexId) { return OutputUtils.byteArrayToHexString(key); } }; dumpDB(dbDir, logDir, false, formatter, out); } }