}
private void setupDatabase(DatabaseKey databaseKey) throws MasterKeysWrongPasswordException, MasterKeysFileSizeException, IOException {
/* FIXME: Backup the database! */
ObjectContainer database;
File dbFileBackup = new File(dbFile.getPath()+".tmp");
File dbFileCryptBackup = new File(dbFileCrypt.getPath()+".tmp");
if(dbFileBackup.exists() && !dbFile.exists()) {
if(!dbFileBackup.renameTo(dbFile)) {
throw new IOException("Database backup file "+dbFileBackup+" exists but cannot be renamed to "+dbFile+". Not loading database, please fix permissions problems!");
}
}
if(dbFileCryptBackup.exists() && !dbFileCrypt.exists()) {
if(!dbFileCryptBackup.renameTo(dbFileCrypt)) {
throw new IOException("Database backup file "+dbFileCryptBackup+" exists but cannot be renamed to "+dbFileCrypt+". Not loading database, please fix permissions problems!");
}
}
try {
if(securityLevels.getPhysicalThreatLevel() == PHYSICAL_THREAT_LEVEL.MAXIMUM) {
if(dbFile.exists())
FileUtil.secureDelete(dbFile);
if(dbFileCrypt.exists())
FileUtil.secureDelete(dbFileCrypt);
if(dbFileBackup.exists())
FileUtil.secureDelete(dbFile);
if(dbFileCryptBackup.exists())
FileUtil.secureDelete(dbFileCrypt);
return; // No need to migrate
} else if(dbFile.exists()) {
// Just open it.
database = Db4o.openFile(getNewDatabaseConfiguration(null), dbFile.toString());
} else if((dbFileCrypt.exists())) {
// Open encrypted, regardless of seclevel.
database = openCryptDatabase(databaseKey);
} else return;
} catch (Db4oException e) {
database = null;
System.err.println("Failed to open database: "+e);
e.printStackTrace();
}
// DUMP DATABASE CONTENTS
if(logDEBUG && database != null) {
try {
System.err.println("DUMPING DATABASE CONTENTS:");
ObjectSet<Object> contents = database.queryByExample(new Object());
Map<String,Integer> map = new HashMap<String, Integer>();
for(Object o: contents) {
String name = o.getClass().getName();
if((map.get(name)) != null) {
map.put(name, map.get(name)+1);
} else {
map.put(name, 1);
}
// Activated to depth 1
try {
Logger.minor(this, "DATABASE: "+o.getClass()+":"+o+":"+database.ext().getID(o));
} catch (Throwable t) {
Logger.minor(this, "CAUGHT "+t+" FOR CLASS "+o.getClass());
}
database.deactivate(o, 1);
}
int total = 0;
for(Map.Entry<String,Integer> entry : map.entrySet()) {
System.err.println(entry.getKey()+" : "+entry.getValue());
total += entry.getValue();
}
// Some structures e.g. collections are sensitive to the activation depth.
// If they are activated to depth 1, they are broken, and activating them to
// depth 2 does NOT un-break them! Hence we need to deactivate (above) and
// GC here...
System.gc();
System.runFinalization();
System.gc();
System.runFinalization();
System.err.println("END DATABASE DUMP: "+total+" objects");
} catch (Db4oException e) {
System.err.println("Unable to dump database contents. Treating as corrupt database.");
e.printStackTrace();
try {
database.rollback();
} catch (Throwable t) {} // ignore, closing
try {
database.close();
} catch (Throwable t) {} // ignore, closing
database = null;
} catch (IllegalArgumentException e) {
// Urrrrgh!
System.err.println("Unable to dump database contents. Treating as corrupt database.");
e.printStackTrace();
try {
database.rollback();
} catch (Throwable t) {} // ignore, closing
try {
database.close();
} catch (Throwable t) {} // ignore, closing
database = null;
}
}