提交 a75bacaa authored 作者: Thomas Mueller's avatar Thomas Mueller

The ChangeFileEncryption and Backup tools will now fail if the database is still in use.

上级 2c065a21
......@@ -8,7 +8,10 @@ package org.h2.store;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.message.TraceSystem;
import org.h2.util.FileUtils;
import org.h2.util.New;
......@@ -37,14 +40,37 @@ public class FileLister {
return null;
}
/**
* Try to lock the database, and then unlock it. If this worked, the
* .lock.db file will be removed.
*
* @param files the database files to check
* @param message the text to include in the error message
* @throws SQLException if it failed
*/
public static void tryUnlockDatabase(ArrayList<String> files, String message) throws SQLException {
for (String fileName : files) {
if (fileName.endsWith(Constants.SUFFIX_LOCK_FILE)) {
FileLock lock = new FileLock(new TraceSystem(null, false), fileName, Constants.LOCK_SLEEP);
try {
lock.lock(FileLock.LOCK_FILE);
lock.unlock();
} catch (SQLException e) {
throw Message.getSQLException(
ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, message);
}
}
}
}
/**
* Get the list of database files.
*
* @param dir the directory (null for the current directory)
* @param db the database name (null for all databases)
* @param all if true, files such as the lock, trace, hash index, and lob
* files are included. If false, only data, index and log files
* are returned
* @param all if true, files such as the lock, trace, and lob
* files are included. If false, only data, index, log,
* and lob files are returned
* @return the list of files
*/
public static ArrayList<String> getDatabaseFiles(String dir, String db, boolean all) throws SQLException {
......
......@@ -24,6 +24,8 @@ import org.h2.util.Tool;
/**
* Creates a backup of a database.
* <br />
* The database must be closed before using this tool.
* @h2.resource
*/
public class Backup extends Tool {
......@@ -90,6 +92,7 @@ public class Backup extends Tool {
private void process(String zipFileName, String directory, String db, boolean quiet) throws SQLException {
ArrayList<String> list = FileLister.getDatabaseFiles(directory, db, true);
FileLister.tryUnlockDatabase(list, "backup");
if (list.size() == 0) {
if (!quiet) {
printNoDatabaseFilesFound(directory, db);
......
......@@ -20,6 +20,7 @@ import org.h2.util.Tool;
* Allows changing the database file encryption password or algorithm.
* <br />
* This tool can not be used to change a password of a user.
* The database must be closed before using this tool.
* @h2.resource
*/
public class ChangeFileEncryption extends Tool {
......@@ -137,12 +138,14 @@ public class ChangeFileEncryption extends Tool {
change.decrypt = getFileEncryptionKey(decryptPassword);
change.encrypt = getFileEncryptionKey(encryptPassword);
// first, test only if the file can be renamed
// (to find errors with locked files early)
ArrayList<String> files = FileLister.getDatabaseFiles(dir, db, false);
ArrayList<String> files = FileLister.getDatabaseFiles(dir, db, true);
FileLister.tryUnlockDatabase(files, "encryption");
files = FileLister.getDatabaseFiles(dir, db, false);
if (files.size() == 0 && !quiet) {
printNoDatabaseFilesFound(dir, db);
}
// first, test only if the file can be renamed
// (to find errors with locked files early)
for (String fileName : files) {
String temp = dir + "/temp.db";
FileUtils.delete(temp);
......
......@@ -452,6 +452,12 @@ public class TestTools extends TestBase {
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
assertTrue(rs.next());
assertFalse(rs.next());
try {
Backup.main("-file", fileName, "-dir", baseDir, "-db", "utils", "-quiet");
fail();
} catch (SQLException e) {
assertKnownException(e);
}
conn.close();
DeleteDbFiles.main("-dir", baseDir, "-db", "utils", "-quiet");
}
......@@ -473,6 +479,13 @@ public class TestTools extends TestBase {
baseDir + "/utils;CIPHER=AES", "sa", "def 123");
stat = conn.createStatement();
stat.execute("SELECT * FROM TEST");
try {
args = new String[] { "-dir", baseDir, "-db", "utils", "-cipher", "AES", "-decrypt", "def", "-quiet" };
ChangeFileEncryption.main(args);
fail();
} catch (SQLException e) {
assertKnownException(e);
}
conn.close();
args = new String[] { "-dir", baseDir, "-db", "utils", "-quiet" };
DeleteDbFiles.main(args);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论