--- java/src/org/apache/xindice/tools/DatabaseRebuild.java (revision 518809)
+++ java/src/org/apache/xindice/tools/DatabaseRebuild.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.xindice.xml.dom.DOMParser;
import org.apache.xindice.core.filer.BTreeFiler;
import org.apache.xindice.core.filer.BTreeCallback;
+import org.apache.xindice.core.filer.BTreeException;
import org.apache.xindice.core.data.Value;
import org.apache.xindice.core.data.Key;
import org.apache.xindice.core.Database;
@@ -29,7 +30,8 @@
import org.apache.xindice.core.DBException;
import org.apache.xindice.core.indexer.Indexer;
import org.apache.xindice.util.Configuration;
-import org.apache.xindice.util.XindiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.IOException;
@@ -41,152 +43,233 @@
*/
public class DatabaseRebuild {
+ private static final int CMD_ALL = 0;
private static final int CMD_COPY = 1;
private static final int CMD_INDEX = 2;
- private static Database db;
- private static String path;
- private static boolean removeBackupFiles;
- private static int command;
+ private static final char NOT_RAN = '_';
+ private static final char SUCCESS = '*';
+ private static final char ERROR = '!';
+ private static final Log log = LogFactory.getLog(DatabaseRebuild.class);
public static void main(String[] args) throws Exception {
- if (args.length < 2 || !("copy".equals(args[0]) || "index".equals(args[0])) ||
- args[1] == null || args[1].length() == 0) {
+ if (args.length < 2 || args[1] == null || args[1].length() == 0 ||
+ !("copy".equals(args[0]) || "index".equals(args[0]) || "rebuild".equals(args[0]))) {
usage();
- return;
+ System.exit(1);
}
- command = "copy".equals(args[0]) ? CMD_COPY : CMD_INDEX;
+ int command;
+ if ("copy".equals(args[0])) {
+ command = CMD_COPY;
+ } else if ("index".equals(args[0])) {
+ command = CMD_INDEX;
+ } else {
+ command = CMD_ALL;
+ }
+
String dbLocation = args[1];
- if (args.length > 2 && args[2].equals("--remove")) {
- removeBackupFiles = true;
+
+ File location = new File(dbLocation);
+ dbLocation = location.getAbsolutePath();
+ String name = location.getName();
+
+ if ("".equals(name) || !location.exists() || !location.isDirectory()) {
+ System.out.println("Database path must point to existing database directory");
+ System.exit(1);
}
- String config = "";
- db = new Database();
+ // create minimal database configuration instead of trying to locate system.xml
+ String config = "";
+ Database db = new Database();
+ boolean status = true;
try {
+ System.out.println();
+ System.out.println("CI\tCollection name");
+
db.setConfig(new Configuration(DOMParser.toDocument(config)));
- path = db.getCollectionRoot().getPath();
- processChildCollections("/");
+ if (log.isInfoEnabled()) {
+ log.info("Rebuilding collections...");
+ }
+ status = processCollection(db, command);
} finally {
db.close();
+
+ System.out.println();
+ if (status) {
+ System.out.println("Rebuilding database was successfull");
+ } else {
+ System.out.println("Rebuilding database failed. Please check logs for more detail");
+ }
+
+ System.exit(status ? 0 : 2);
}
+
}
private static void usage() {
System.out.println("Commands:");
- System.out.println("copy [--remove]");
- System.out.println("index ");
+ System.out.println("copy -v");
+ System.out.println("index -v");
+ System.out.println("rebuild -v");
}
- private static void processChildCollections(String colRoot) {
- System.out.println("Getting child collections for " + colRoot);
+ private static boolean processCollection(Collection col, int command) {
+ String name = col.getCanonicalName();
+ boolean status;
+
try {
- // Get a Collection reference
- Collection col = db.getCollection(colRoot);
- if (col == null) {
- System.out.println("Error fetching collection '" + colRoot + "'");
- return;
+ if (log.isInfoEnabled()) {
+ log.info("Processing collection " + name);
}
- processCollection(col, colRoot);
+ char copy = NOT_RAN;
+ char index = NOT_RAN;
+ switch (command) {
+ case CMD_COPY:
+ status = rebuildCollection(col);
+ copy = status ? SUCCESS : ERROR;
+ break;
+ case CMD_INDEX:
+ status = rebuildIndex(col);
+ index = status ? SUCCESS : ERROR;
+ break;
+ default:
+ status = rebuildCollection(col);
+ copy = status ? SUCCESS : ERROR;
+ if (status) {
+ status = rebuildIndex(col);
+ index = status ? SUCCESS : ERROR;
+ }
+ break;
+ }
+
+ System.out.println(Character.toString(copy) + Character.toString(index) + "\t" + name);
+
String[] colNames = col.listCollections();
for (int i = 0; i < colNames.length; i++) {
- processChildCollections(colRoot + colNames[i] + "/");
+ boolean result = processCollection(col.getCollection(colNames[i]), command);
+ status = status && result;
}
- } catch (Exception e) {
- System.out.println("Got an excefption when processing collection: " + colRoot);
- e.printStackTrace();
+ } catch (DBException e) {
+ log.error("Got an exception when processing collection " + name, e);
+
+ return false;
}
+
+ return status;
}
- private static void processCollection(Collection col, String location) throws XindiceException, IOException {
- switch (command) {
- case CMD_INDEX:
- rebuildIndex(col);
- break;
+ private static boolean rebuildCollection(Collection col) {
+ String canonicalName = col.getCanonicalName();
- case CMD_COPY:
- rebuildCollection(col, location, col.getName());
- break;
+ if (!(col.getFiler() instanceof BTreeFiler)) {
+ if (log.isInfoEnabled()) {
+ log.info("Filer for collection " + canonicalName + " is not BTreeFiler. Skipping...");
+ }
+ return true;
}
- }
- private static void rebuildCollection(Collection col, String location, String name) throws XindiceException, IOException {
- if (!(col.getFiler() instanceof BTreeFiler)) {
- System.out.println("Filer for collection " + location + " is not BTreeFiler. Skipping...");
- return;
+ // close collection's filer
+ try {
+ col.getFiler().close();
+ } catch (DBException e) {
+ log.error("Could not close filer for collection " + canonicalName, e);
+ return false;
}
- // close collection and its filer
- col.close();
-
- System.out.println("Processing collection " + location);
-
- File root = new File(path + location);
-
- // backup
- String fileName = path + location + "/" + name;
- // FIXME What if copy fails. It's probably a better idea to first make a copy,
- // and rename after that?
- new File(fileName + ".tbl").renameTo(new File(fileName + ".old.tbl"));
-
// prepare
- BTreeCopy filer = new BTreeCopy();
- filer.setLocation(root, name + ".old");
- filer.setConfig(col.getFiler().getConfig());
- if (!filer.exists()) {
- System.out.println("Filer for " + fileName + ".old.tbl does not exists");
- return;
+ BTreeCopy oldFiler = new BTreeCopy();
+ oldFiler.setLocation(col.getCollectionRoot(), col.getName());
+ oldFiler.setConfig(col.getFiler().getConfig());
+ String oldFileName = oldFiler.getFilerFile().getAbsolutePath();
+ if (!oldFiler.exists()) {
+ log.error("Filer for " + oldFileName + " does not exists");
+ return false;
}
- BTreeFiler newFiler = new BTreeFiler();
- newFiler.setLocation(root, name);
+ BTreeCopy newFiler = new BTreeCopy();
+ newFiler.setLocation(col.getCollectionRoot(), col.getName() + ".rebuild");
newFiler.setConfig(col.getFiler().getConfig());
+ String newFileName = newFiler.getFilerFile().getAbsolutePath();
if (newFiler.exists()) {
- System.out.println("Filer for " + fileName + ".tbl already exists");
- return;
+ log.error("Filer for " + newFileName + " already exists");
+ return false;
}
// copy
- newFiler.create();
+ if (!copy(oldFiler, newFiler, canonicalName)) {
+ newFiler.deleteFile();
+ return false;
+ }
+
+ oldFiler.deleteFile();
+ if (!newFiler.getFilerFile().renameTo(oldFiler.getFilerFile())) {
+ log.error("Could not rename successfully rebuilt file " + newFileName + " to " + oldFileName);
+ return false;
+ }
+
try {
- filer.open();
+ col.getFiler().open();
+ } catch (DBException e) {
+ log.error("Could not open new file " + oldFileName, e);
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean copy(BTreeCopy oldFiler, BTreeCopy newFiler, String canonicalName) {
+ try {
+ newFiler.create();
+ oldFiler.open();
newFiler.open();
-
- filer.copy(newFiler);
- if (removeBackupFiles) {
- filer.deleteFile();
- }
+ oldFiler.copy(newFiler);
+ } catch (Exception e) {
+ log.error("Error copying collection " + canonicalName, e);
+ return false;
} finally {
try {
- filer.close();
- } catch (Exception e) {
- e.printStackTrace();
+ oldFiler.close();
+ } catch (DBException e) {
+ if (log.isWarnEnabled()) log.warn(e);
}
try {
newFiler.close();
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (DBException e) {
+ if (log.isWarnEnabled()) log.warn(e);
}
}
+
+ return true;
}
- private static void rebuildIndex(Collection col) throws DBException {
- if (col.getFiler() != null) {
+ private static boolean rebuildIndex(Collection col) {
+ if (col.getFiler() == null) {
+ return true;
+ }
+
+ try {
String[] list = col.listIndexers();
for (int i = 0; i < list.length; i++) {
Indexer idx = col.getIndexer(list[i]);
Configuration idxConf = idx.getConfig();
- System.out.println("Rebuilding index " + list[i] + " for collection " + col.getName());
+ if (log.isInfoEnabled()) {
+ log.info("Rebuilding index " + list[i] + " for collection " + col.getCanonicalName());
+ }
col.dropIndexer(idx);
col.createIndexer(idxConf);
}
+ } catch (DBException e) {
+ log.error("Could not rebuild index for collection " + col.getCanonicalName(), e);
+ return false;
}
+
+ return true;
}
private static class BTreeCopy extends BTreeFiler {
@@ -194,13 +277,17 @@
return super.readValue(pointer);
}
- private void copy(BTreeFiler newFiler) throws XindiceException, IOException {
+ private void copy(BTreeFiler newFiler) throws IOException, BTreeException {
query(null, new CopyCallback(this, newFiler));
}
private boolean deleteFile() {
return getFile().delete();
}
+
+ private File getFilerFile() {
+ return getFile();
+ }
}
private static class CopyCallback implements BTreeCallback {