boolean renamed = false;
boolean renameFailed = false;
File oldbackup = null;
File backupcopy = null;
OutputStreamWriter historyFile = null;
StorageFile dbHistoryFile = null;
File backupHistoryFile = null;
LogInstant backupInstant = logFactory.getFirstUnflushedInstant();
try
{
// get name of the current db, ie. database directory of current db.
StorageFile dbase = storageFactory.newStorageFile(null);
String canonicalDbName = storageFactory.getCanonicalName();
int lastSep =
canonicalDbName.lastIndexOf(storageFactory.getSeparator());
String dbname =
canonicalDbName.substring(lastSep + 1);
// append to end of history file
historyFile =
privFileWriter(
storageFactory.newStorageFile(BACKUP_HISTORY), true);
backupcopy = new File(backupDir, dbname);
logHistory(
historyFile,
MessageService.getTextMessage(
MessageId.STORE_BACKUP_STARTED,
canonicalDbName,
getFilePath(backupcopy)));
// check if a backup copy of this database already exists,
if (privExists(backupcopy))
{
// first make a backup of the backup
oldbackup = new File(backupDir, dbname+".OLD");
if (privExists(oldbackup))
{
if (privIsDirectory(oldbackup))
privRemoveDirectory(oldbackup);
else
privDelete(oldbackup);
}
if (!privRenameTo(backupcopy,oldbackup))
{
renameFailed = true;
throw StandardException.
newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE,
backupcopy, oldbackup);
}
else
{
logHistory(
historyFile,
MessageService.getTextMessage(
MessageId.STORE_MOVED_BACKUP,
getFilePath(backupcopy),
getFilePath(oldbackup)));
renamed = true;
}
}
// create the backup database directory
if (!privMkdirs(backupcopy))
{
throw StandardException.newException(
SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
(File) backupcopy);
}
dbHistoryFile = storageFactory.newStorageFile(BACKUP_HISTORY);
backupHistoryFile = new File(backupcopy, BACKUP_HISTORY);
// copy the history file into the backup.
if(!privCopyFile(dbHistoryFile, backupHistoryFile))
throw StandardException.
newException(SQLState.RAWSTORE_ERROR_COPYING_FILE,
dbHistoryFile, backupHistoryFile);
// if they are any jar file stored in the database, copy them into
// the backup.
StorageFile jarDir =
storageFactory.newStorageFile(FileResource.JAR_DIRECTORY_NAME);
if (privExists(jarDir))
{
// find the list of schema directories under the jar dir and
// then copy only the plain files under those directories. One
// could just use the recursive copy of directory to copy all
// the files under the jar dir, but the problem with that is if
// a user gives jar directory as the backup path by mistake,
// copy will fail while copying the backup dir onto itself in
// recursion
String [] jarSchemaList = privList(jarDir);
File backupJarDir = new File(backupcopy,
FileResource.JAR_DIRECTORY_NAME);
// Create the backup jar directory
if (!privMkdirs(backupJarDir))
{
throw StandardException.newException(
SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
(File) backupJarDir);
}
for (int i = 0; i < jarSchemaList.length; i++)
{
StorageFile jarSchemaDir =
storageFactory.newStorageFile(jarDir, jarSchemaList[i]);
File backupJarSchemaDir =
new File(backupJarDir, jarSchemaList[i]);
if (!privCopyDirectory(jarSchemaDir, backupJarSchemaDir,
(byte[])null, null, false))
{
throw StandardException.
newException(SQLState.RAWSTORE_ERROR_COPYING_FILE,
jarSchemaDir, backupJarSchemaDir);
}
}
}
// save service properties into the backup, Read in property
// from service.properties file, remove logDevice from it,
// then write it to the backup.
StorageFile logdir = logFactory.getLogDirectory();
try
{
String name = Monitor.getMonitor().getServiceName(this);
PersistentService ps =
Monitor.getMonitor().getServiceType(this);
String fullName = ps.getCanonicalServiceName(name);
Properties prop =
ps.getServiceProperties(fullName, (Properties)null);
StorageFile defaultLogDir =
storageFactory.newStorageFile(
LogFactory.LOG_DIRECTORY_NAME);
if (!logdir.equals(defaultLogDir))
{
prop.remove(Attribute.LOG_DEVICE);
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(
prop.getProperty(Attribute.LOG_DEVICE) == null,
"cannot get rid of logDevice property");
}
logHistory(historyFile,
MessageService.getTextMessage(
MessageId.STORE_EDITED_SERVICEPROPS));
}
// save the service properties into the backup.
ps.saveServiceProperties(backupcopy.getPath(), prop, false);
}
catch(StandardException se)
{
logHistory(
historyFile,
MessageService.getTextMessage(
MessageId.STORE_ERROR_EDIT_SERVICEPROPS) + se);
return; // skip the rest and let finally block clean up
}
// Incase of encrypted database and the key is an external
// encryption key, there is an extra file with name
// Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE, this file should be
// copied in to the backup.
StorageFile verifyKeyFile =
storageFactory.newStorageFile(
Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
if (privExists(verifyKeyFile))
{
File backupVerifyKeyFile =