/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Random;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.store.FileLister;
import org.h2.store.fs.FileSystem;
import org.h2.test.TestBase;
import org.h2.test.trace.Player;
import org.h2.test.utils.AssertThrows;
import org.h2.tools.Backup;
import org.h2.tools.ChangeFileEncryption;
import org.h2.tools.Console;
import org.h2.tools.ConvertTraceFile;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Recover;
import org.h2.tools.Restore;
import org.h2.tools.RunScript;
import org.h2.tools.Script;
import org.h2.tools.Server;
import org.h2.tools.SimpleResultSet;
import org.h2.tools.SimpleResultSet.SimpleArray;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.Task;
/**
* Tests the database tools.
*/
public class TestTools extends TestBase {
private static String lastUrl;
private Server server;
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
if (config.networked) {
return;
}
org.h2.Driver.load();
testTcpServerWithoutPort();
testConsole();
testJdbcDriverUtils();
testWrongServer();
deleteDb("utils");
testDeleteFiles();
testScriptRunscriptLob();
deleteDb("utils");
testServerMain();
testRemove();
testConvertTraceFile();
testManagementDb();
testChangeFileEncryption(false);
if (!config.splitFileSystem) {
testChangeFileEncryption(true);
}
testServer();
testScriptRunscript();
testBackupRestore();
testRecover();
testSimpleResultSet();
deleteDb("utils");
IOUtils.delete(getBaseDir() + "/b2.sql");
IOUtils.delete(getBaseDir() + "/b2.sql.txt");
IOUtils.delete(getBaseDir() + "/b2.zip");
}
private void testTcpServerWithoutPort() throws Exception {
Server s1 = Server.createTcpServer().start();
Server s2 = Server.createTcpServer().start();
assertTrue(s1.getPort() != s2.getPort());
s1.stop();
s2.stop();
s1 = Server.createTcpServer("-tcpPort", "9123").start();
assertEquals(9123, s1.getPort());
createClassProxy(Server.class);
assertThrows(ErrorCode.EXCEPTION_OPENING_PORT_2,
Server.createTcpServer("-tcpPort", "9123")).start();
s1.stop();
}
private void testConsole() throws Exception {
String old = System.getProperty(SysProperties.H2_BROWSER);
Console c = new Console();
c.setOut(new PrintStream(new ByteArrayOutputStream()));
try {
// start including browser
lastUrl = "-";
System.setProperty(SysProperties.H2_BROWSER, "call:" + TestTools.class.getName() + ".openBrowser");
c.runTool("-web", "-webPort", "9002", "-tool", "-browser", "-tcp", "-tcpPort", "9003", "-pg", "-pgPort", "9004");
assertContains(lastUrl, ":9002");
c.shutdown();
// check if starting the browser works
c.runTool("-web", "-webPort", "9002", "-tool");
lastUrl = "-";
c.actionPerformed(new ActionEvent(this, 0, "console"));
assertContains(lastUrl, ":9002");
lastUrl = "-";
// double-click prevention is 100 ms
Thread.sleep(200);
MouseEvent me = new MouseEvent(new Button(), 0, 0, 0, 0, 0, 0, false, MouseEvent.BUTTON1);
c.mouseClicked(me);
assertContains(lastUrl, ":9002");
lastUrl = "-";
// no delay - ignore because it looks like a double click
c.mouseClicked(me);
assertEquals("-", lastUrl);
// open the window
c.actionPerformed(new ActionEvent(this, 0, "status"));
c.actionPerformed(new ActionEvent(this, 0, "exit"));
// check if the service was stopped
c.runTool("-webPort", "9002");
c.shutdown();
// trying to use the same port for two services should fail,
// but also stop the first service
createClassProxy(c.getClass());
assertThrows(ErrorCode.EXCEPTION_OPENING_PORT_2, c).
runTool("-web", "-webPort", "9002", "-tcp", "-tcpPort", "9002");
c.runTool("-web", "-webPort", "9002");
c.shutdown();
} finally {
if (old != null) {
System.setProperty(SysProperties.H2_BROWSER, old);
} else {
System.clearProperty(SysProperties.H2_BROWSER);
}
}
}
/**
* This method is called via reflection.
*
* @param url the browser url
*/
public static void openBrowser(String url) {
lastUrl = url;
}
private void testSimpleResultSet() throws Exception {
SimpleResultSet rs;
rs = new SimpleResultSet();
rs.addColumn(null, 0, 0, 0);
rs.addRow(1);
createClassProxy(rs.getClass());
assertThrows(IllegalStateException.class, rs).
addColumn(null, 0, 0, 0);
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("1", rs.getString(1));
assertEquals("1", rs.getString("C1"));
assertFalse(rs.wasNull());
assertEquals("C1", rs.getMetaData().getColumnLabel(1));
assertEquals("C1", rs.getColumnName(1));
assertEquals(ResultSetMetaData.columnNullableUnknown, rs.getMetaData().isNullable(1));
assertFalse(rs.getMetaData().isAutoIncrement(1));
assertTrue(rs.getMetaData().isCaseSensitive(1));
assertFalse(rs.getMetaData().isCurrency(1));
assertFalse(rs.getMetaData().isDefinitelyWritable(1));
assertTrue(rs.getMetaData().isReadOnly(1));
assertTrue(rs.getMetaData().isSearchable(1));
assertTrue(rs.getMetaData().isSigned(1));
assertFalse(rs.getMetaData().isWritable(1));
assertEquals(null, rs.getMetaData().getCatalogName(1));
assertEquals(null, rs.getMetaData().getColumnClassName(1));
assertEquals(null, rs.getMetaData().getColumnTypeName(1));
assertEquals(null, rs.getMetaData().getSchemaName(1));
assertEquals(null, rs.getMetaData().getTableName(1));
assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
assertEquals(1, rs.getColumnCount());
rs = new SimpleResultSet();
rs.addColumn("a", Types.BIGINT, 0, 0);
rs.addColumn("b", Types.BINARY, 0, 0);
rs.addColumn("c", Types.BOOLEAN, 0, 0);
rs.addColumn("d", Types.DATE, 0, 0);
rs.addColumn("e", Types.DECIMAL, 0, 0);
rs.addColumn("f", Types.FLOAT, 0, 0);
rs.addColumn("g", Types.VARCHAR, 0, 0);
rs.addColumn("h", Types.ARRAY, 0, 0);
rs.addColumn("i", Types.TIME, 0, 0);
rs.addColumn("j", Types.TIMESTAMP, 0, 0);
Date d = Date.valueOf("2001-02-03");
byte[] b = {(byte) 0xab};
Object[] a = {1, 2};
Time t = Time.valueOf("10:20:30");
Timestamp ts = Timestamp.valueOf("2002-03-04 10:20:30");
rs.addRow(1, b, true, d, "10.3", Math.PI, "-3", a, t, ts);
rs.next();
assertEquals(1, rs.getLong(1));
assertEquals((byte) 1, rs.getByte(1));
assertEquals((short) 1, rs.getShort(1));
assertEquals(1, rs.getLong("a"));
assertEquals((byte) 1, rs.getByte("a"));
assertEquals(1, rs.getInt("a"));
assertEquals((short) 1, rs.getShort("a"));
assertTrue(rs.getObject(1).getClass() == Integer.class);
assertTrue(rs.getObject("a").getClass() == Integer.class);
assertEquals(b, rs.getBytes(2));
assertEquals(b, rs.getBytes("b"));
assertTrue(rs.getBoolean(3));
assertTrue(rs.getBoolean("c"));
assertEquals(d.getTime(), rs.getDate(4).getTime());
assertEquals(d.getTime(), rs.getDate("d").getTime());
assertTrue(new BigDecimal("10.3").equals(rs.getBigDecimal(5)));
assertTrue(new BigDecimal("10.3").equals(rs.getBigDecimal("e")));
assertEquals(10.3, rs.getDouble(5));
assertEquals((float) 10.3, rs.getFloat(5));
assertTrue(Math.PI == rs.getDouble(6));
assertTrue(Math.PI == rs.getDouble("f"));
assertTrue((float) Math.PI == rs.getFloat(6));
assertTrue((float) Math.PI == rs.getFloat("f"));
assertEquals(-3, rs.getInt(7));
assertEquals(-3, rs.getByte(7));
assertEquals(-3, rs.getShort(7));
assertEquals(-3, rs.getLong(7));
Object[] a2 = (Object[]) rs.getArray(8).getArray();
assertEquals(2, a2.length);
assertTrue(a == a2);
SimpleArray array = (SimpleArray) rs.getArray("h");
assertEquals(Types.NULL, array.getBaseType());
assertEquals("NULL", array.getBaseTypeName());
a2 = (Object[]) array.getArray();
array.free();
assertEquals(2, a2.length);
assertTrue(a == a2);
assertTrue(t == rs.getTime("i"));
assertTrue(t == rs.getTime(9));
assertTrue(ts == rs.getTimestamp("j"));
assertTrue(ts == rs.getTimestamp(10));
assertThrows(ErrorCode.INVALID_VALUE_2, (ResultSet) rs).
getString(11);
assertThrows(ErrorCode.COLUMN_NOT_FOUND_1, (ResultSet) rs).
getString("NOT_FOUND");
// all 'updateX' methods are not supported
for (Method m: rs.getClass().getMethods()) {
if (m.getName().startsWith("update")) {
int len = m.getParameterTypes().length;
Object[] params = new Object[len];
int i = 0;
for (Class<?> type : m.getParameterTypes()) {
Object o = null;
if (type == int.class) {
o = 1;
} else if (type == byte.class) {
o = (byte) 1;
} else if (type == double.class) {
o = (double) 1;
} else if (type == float.class) {
o = (float) 1;
} else if (type == long.class) {
o = (long) 1;
} else if (type == short.class) {
o = (short) 1;
} else if (type == boolean.class) {
o = false;
}
params[i] = o;
i++;
}
try {
m.invoke(rs, params);
} catch (InvocationTargetException e) {
SQLException e2 = (SQLException) e.getTargetException();
assertEquals(ErrorCode.FEATURE_NOT_SUPPORTED_1, e2.getErrorCode());
}
}
}
assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
assertEquals(0, rs.getFetchSize());
assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType());
assertTrue(rs.getStatement() == null);
assertFalse(rs.isClosed());
rs.beforeFirst();
assertEquals(0, rs.getRow());
assertTrue(rs.next());
assertFalse(rs.isClosed());
assertEquals(1, rs.getRow());
assertFalse(rs.next());
assertThrows(ErrorCode.NO_DATA_AVAILABLE, (ResultSet) rs).
getInt(1);
assertTrue(rs.isClosed());
assertEquals(0, rs.getRow());
}
private void testJdbcDriverUtils() {
assertEquals("org.h2.Driver", JdbcUtils.getDriver("jdbc:h2:~/test"));
assertEquals("org.postgresql.Driver", JdbcUtils.getDriver("jdbc:postgresql:test"));
assertEquals(null, JdbcUtils.getDriver("jdbc:unknown:test"));
}
private void testWrongServer() throws Exception {
// try to connect when the server is not running
assertThrows(ErrorCode.CONNECTION_BROKEN_1, this).
getConnection("jdbc:h2:tcp://localhost:9001/test");
final ServerSocket serverSocket = new ServerSocket(9001);
Task task = new Task() {
public void call() throws Exception {
Socket socket = serverSocket.accept();
byte[] data = new byte[1024];
data[0] = 'x';
socket.getOutputStream().write(data);
socket.close();
}
};
task.execute();
Thread.sleep(100);
try {
getConnection("jdbc:h2:tcp://localhost:9001/test");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.CONNECTION_BROKEN_1, e.getErrorCode());
}
serverSocket.close();
task.get();
}
private void testDeleteFiles() throws SQLException {
deleteDb("utilsMore");
Connection conn = getConnection("utilsMore");
Statement stat = conn.createStatement();
stat.execute("create table test(c clob) as select space(10000) from dual");
conn.close();
DeleteDbFiles.execute(getBaseDir(), "utils", true);
conn = getConnection("utilsMore");
stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from test");
rs.next();
rs.getString(1);
conn.close();
deleteDb("utilsMore");
}
private void testServerMain() throws SQLException {
String result;
Connection conn;
result = runServer(0, new String[]{"-?"});
assertTrue(result.indexOf("Starts the H2 Console") >= 0);
assertTrue(result.indexOf("Unknown option") < 0);
result = runServer(1, new String[]{"-xy"});
assertTrue(result.indexOf("Starts the H2 Console") >= 0);
assertTrue(result.indexOf("Unsupported option") >= 0);
result = runServer(0, new String[]{"-tcp", "-tcpPort", "9001", "-tcpPassword", "abc"});
assertTrue(result.indexOf("tcp://") >= 0);
assertTrue(result.indexOf(":9001") >= 0);
assertTrue(result.indexOf("only local") >= 0);
assertTrue(result.indexOf("Starts the H2 Console") < 0);
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9001/mem:", "sa", "sa");
conn.close();
result = runServer(0, new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce"});
assertTrue(result.indexOf("Shutting down") >= 0);
result = runServer(0, new String[]{"-tcp", "-tcpAllowOthers", "-tcpPort", "9001", "-tcpPassword", "abcdef", "-tcpSSL"});
assertTrue(result.indexOf("ssl://") >= 0);
assertTrue(result.indexOf(":9001") >= 0);
assertTrue(result.indexOf("others can") >= 0);
assertTrue(result.indexOf("Starts the H2 Console") < 0);
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
conn.close();
result = runServer(0, new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "abcdef"});
assertTrue(result.indexOf("Shutting down") >= 0);
assertThrows(ErrorCode.CONNECTION_BROKEN_1, this).
getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
result = runServer(0, new String[]{
"-web", "-webPort", "9002", "-webAllowOthers", "-webSSL",
"-pg", "-pgAllowOthers", "-pgPort", "9003",
"-tcp", "-tcpAllowOthers", "-tcpPort", "9006", "-tcpPassword", "abc"});
Server stop = server;
assertTrue(result.indexOf("https://") >= 0);
assertTrue(result.indexOf(":9002") >= 0);
assertTrue(result.indexOf("pg://") >= 0);
assertTrue(result.indexOf(":9003") >= 0);
assertTrue(result.indexOf("others can") >= 0);
assertTrue(result.indexOf("only local") < 0);
assertTrue(result.indexOf("tcp://") >= 0);
assertTrue(result.indexOf(":9006") >= 0);
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9006/mem:", "sa", "sa");
conn.close();
result = runServer(0, new String[]{"-tcpShutdown", "tcp://localhost:9006", "-tcpPassword", "abc", "-tcpShutdownForce"});
assertTrue(result.indexOf("Shutting down") >= 0);
stop.shutdown();
assertThrows(ErrorCode.CONNECTION_BROKEN_1, this).
getConnection("jdbc:h2:tcp://localhost:9006/mem:", "sa", "sa");
}
private String runServer(int exitCode, String... args) {
ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(buff);
server = new Server();
server.setOut(ps);
int result = 0;
try {
server.runTool(args);
} catch (SQLException e) {
result = 1;
e.printStackTrace(ps);
}
assertEquals(exitCode, result);
ps.flush();
String s = new String(buff.toByteArray());
return s;
}
private void testConvertTraceFile() throws Exception {
deleteDb("toolsConvertTraceFile");
org.h2.Driver.load();
String url = "jdbc:h2:" + getBaseDir() + "/toolsConvertTraceFile";
Connection conn = DriverManager.getConnection(url + ";TRACE_LEVEL_FILE=3", "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar, amount decimal)");
PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?, ?)");
prep.setInt(1, 1);
prep.setString(2, "Hello \\'Joe\n\\'");
prep.setBigDecimal(3, new BigDecimal("10.20"));
prep.executeUpdate();
stat.execute("create table test2(id int primary key,\n" +
"a real, b double, c bigint,\n" +
"d smallint, e boolean, f binary, g date, h time, i timestamp)", Statement.NO_GENERATED_KEYS);
prep = conn.prepareStatement("insert into test2 values(1, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
prep.setFloat(1, Float.MIN_VALUE);
prep.setDouble(2, Double.MIN_VALUE);
prep.setLong(3, Long.MIN_VALUE);
prep.setShort(4, Short.MIN_VALUE);
prep.setBoolean(5, false);
prep.setBytes(6, new byte[] { (byte) 10, (byte) 20 });
prep.setDate(7, java.sql.Date.valueOf("2007-12-31"));
prep.setTime(8, java.sql.Time.valueOf("23:59:59"));
prep.setTimestamp(9, java.sql.Timestamp.valueOf("2007-12-31 23:59:59"));
prep.executeUpdate();
conn.close();
ConvertTraceFile.main("-traceFile", getBaseDir() + "/toolsConvertTraceFile.trace.db",
"-javaClass", getBaseDir() + "/Test",
"-script", getBaseDir() + "/test.sql");
FileSystem fs = FileSystem.getInstance(getBaseDir());
fs.delete(getBaseDir() + "/Test.java");
String trace = getBaseDir() + "/toolsConvertTraceFile.trace.db";
assertTrue(fs.exists(trace));
String newTrace = getBaseDir() + "/test.trace.db";
fs.delete(newTrace);
assertFalse(fs.exists(newTrace));
fs.rename(trace, newTrace);
deleteDb("toolsConvertTraceFile");
Player.main(getBaseDir() + "/test.trace.db");
testTraceFile(url);
deleteDb("toolsConvertTraceFile");
RunScript.main("-url", url, "-user", "sa", "-script", getBaseDir() + "/test.sql");
testTraceFile(url);
deleteDb("toolsConvertTraceFile");
IOUtils.delete(getBaseDir() + "/toolsConvertTraceFile.h2.sql");
IOUtils.delete(getBaseDir() + "/test.sql");
}
private void testTraceFile(String url) throws SQLException {
Connection conn;
Recover.main("-removePassword", "-dir", getBaseDir(), "-db", "toolsConvertTraceFile");
conn = DriverManager.getConnection(url, "sa", "");
Statement stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from test");
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("Hello \\'Joe\n\\'", rs.getString(2));
assertEquals("10.20", rs.getBigDecimal(3).toString());
assertFalse(rs.next());
rs = stat.executeQuery("select * from test2");
rs.next();
assertEquals(Float.MIN_VALUE, rs.getFloat("a"));
assertEquals(Double.MIN_VALUE, rs.getDouble("b"));
assertEquals(Long.MIN_VALUE, rs.getLong("c"));
assertEquals(Short.MIN_VALUE, rs.getShort("d"));
assertTrue(!rs.getBoolean("e"));
assertEquals(new byte[] { (byte) 10, (byte) 20 }, rs.getBytes("f"));
assertEquals("2007-12-31", rs.getString("g"));
assertEquals("23:59:59", rs.getString("h"));
assertEquals("2007-12-31 23:59:59.0", rs.getString("i"));
assertFalse(rs.next());
conn.close();
}
private void testRemove() throws SQLException {
deleteDb("toolsRemove");
org.h2.Driver.load();
String url = "jdbc:h2:" + getBaseDir() + "/toolsRemove";
Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar)");
stat.execute("insert into test values(1, 'Hello')");
conn.close();
Recover.main("-dir", getBaseDir(), "-db", "toolsRemove", "-removePassword");
conn = DriverManager.getConnection(url, "sa", "");
stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from test");
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
conn.close();
deleteDb("toolsRemove");
IOUtils.delete(getBaseDir() + "/toolsRemove.h2.sql");
}
private void testRecover() throws SQLException {
deleteDb("toolsRecover");
org.h2.Driver.load();
String url = getURL("toolsRecover", true);
Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar, b blob, c clob)");
stat.execute("create table \"test 2\"(id int primary key, name varchar)");
stat.execute("comment on table test is ';-)'");
stat.execute("insert into test values(1, 'Hello', SECURE_RAND(4100), '\u00e4' || space(4100))");
ResultSet rs;
rs = stat.executeQuery("select * from test");
rs.next();
byte[] b1 = rs.getBytes(3);
String s1 = rs.getString(4);
conn.close();
Recover.main("-dir", getBaseDir(), "-db", "toolsRecover");
// deleteDb would delete the .lob.db directory as well
// deleteDb("toolsRecover");
ArrayList<String> list = FileLister.getDatabaseFiles(getBaseDir(), "toolsRecover", true);
for (String fileName : list) {
if (!IOUtils.isDirectory(fileName)) {
IOUtils.delete(fileName);
}
}
conn = DriverManager.getConnection(url);
stat = conn.createStatement();
String suffix = ".h2.sql";
stat.execute("runscript from '" + getBaseDir() + "/toolsRecover" + suffix + "'");
rs = stat.executeQuery("select * from \"test 2\"");
assertFalse(rs.next());
rs = stat.executeQuery("select * from test");
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
byte[] b2 = rs.getBytes(3);
String s2 = rs.getString(4);
assertEquals("\u00e4 ", s2.substring(0, 2));
assertEquals(4100, b2.length);
assertEquals(4101, s2.length());
assertEquals(b1, b2);
assertEquals(s1, s2);
assertFalse(rs.next());
conn.close();
deleteDb("toolsRecover");
IOUtils.delete(getBaseDir() + "/toolsRecover.h2.sql");
String dir = getBaseDir() + "/toolsRecover.lobs.db";
IOUtils.deleteRecursive(dir, false);
}
private void testManagementDb() throws SQLException {
int count = getSize(2, 10);
for (int i = 0; i < count; i++) {
Server tcpServer = Server.createTcpServer("-tcpPort", "9192").start();
tcpServer.stop();
tcpServer = Server.createTcpServer("-tcpPassword", "abc", "-tcpPort", "9192").start();
tcpServer.stop();
}
}
private void testScriptRunscriptLob() throws Exception {
org.h2.Driver.load();
String url = "jdbc:h2:" + getBaseDir() + "/utils";
String user = "sa", password = "abc";
String fileName = getBaseDir() + "/b2.sql";
Connection conn = DriverManager.getConnection(url, user, password);
conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, BDATA BLOB, CDATA CLOB)");
PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?, ?)");
prep.setInt(1, 1);
prep.setNull(2, Types.BLOB);
prep.setNull(3, Types.CLOB);
prep.execute();
prep.setInt(1, 2);
prep.setString(2, "face");
prep.setString(3, "face");
prep.execute();
Random random = new Random(1);
prep.setInt(1, 3);
byte[] large = new byte[getSize(10 * 1024, 100 * 1024)];
random.nextBytes(large);
prep.setBytes(2, large);
String largeText = new String(large, "ISO-8859-1");
prep.setString(3, largeText);
prep.execute();
for (int i = 0; i < 2; i++) {
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID");
rs.next();
assertEquals(1, rs.getInt(1));
assertTrue(rs.getString(2) == null);
assertTrue(rs.getString(3) == null);
rs.next();
assertEquals(2, rs.getInt(1));
assertEquals("face", rs.getString(2));
assertEquals("face", rs.getString(3));
rs.next();
assertEquals(3, rs.getInt(1));
assertEquals(large, rs.getBytes(2));
assertEquals(largeText, rs.getString(3));
assertFalse(rs.next());
conn.close();
Script.main("-url", url, "-user", user, "-password", password, "-script", fileName);
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
RunScript.main("-url", url, "-user", user, "-password", password, "-script", fileName);
conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc");
}
conn.close();
}
private void testScriptRunscript() throws SQLException {
org.h2.Driver.load();
String url = "jdbc:h2:" + getBaseDir() + "/utils";
String user = "sa", password = "abc";
String fileName = getBaseDir() + "/b2.sql";
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
Connection conn = DriverManager.getConnection(url, user, password);
conn.createStatement().execute("CREATE TABLE \u00f6()");
conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')");
conn.close();
Script.main("-url", url, "-user", user, "-password", password, "-script", fileName, "-options",
"nodata", "compression", "lzf", "cipher", "xtea", "password", "'123'", "charset", "'utf-8'");
Script.main("-url", url, "-user", user, "-password", password, "-script", fileName + ".txt");
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
RunScript.main("-url", url, "-user", user, "-password", password, "-script", fileName,
"-options", "compression", "lzf", "cipher", "xtea", "password", "'123'", "charset", "'utf-8'");
conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc");
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
assertFalse(rs.next());
rs = conn.createStatement().executeQuery("SELECT * FROM \u00f6");
assertFalse(rs.next());
conn.close();
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
RunScript tool = new RunScript();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
tool.setOut(new PrintStream(buff));
tool.runTool("-url", url, "-user", user, "-password", password, "-script", fileName + ".txt",
"-showResults");
assertTrue(buff.toString().indexOf("Hello") >= 0);
}
private void testBackupRestore() throws SQLException {
org.h2.Driver.load();
String url = "jdbc:h2:" + getBaseDir() + "/utils";
String user = "sa", password = "abc";
final String fileName = getBaseDir() + "/b2.zip";
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
Connection conn = DriverManager.getConnection(url, user, password);
conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')");
conn.close();
Backup.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils", "-quiet");
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
Restore.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils", "-quiet");
conn = DriverManager.getConnection("jdbc:h2:" + getBaseDir() + "/utils", "sa", "abc");
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
assertTrue(rs.next());
assertFalse(rs.next());
new AssertThrows(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1) {
public void test() throws SQLException {
// must fail when the database is in use
Backup.main("-file", fileName, "-dir", getBaseDir(), "-db", "utils");
}
};
conn.close();
DeleteDbFiles.main("-dir", getBaseDir(), "-db", "utils", "-quiet");
}
private void testChangeFileEncryption(boolean split) throws SQLException {
org.h2.Driver.load();
final String dir = (split ? "split:19:" : "") + getBaseDir();
String url = "jdbc:h2:" + dir;
DeleteDbFiles.execute(dir, "utils", true);
Connection conn = DriverManager.getConnection(url + "/utils;CIPHER=XTEA", "sa", "abc 123");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB) " +
"AS SELECT X, SPACE(3000) FROM SYSTEM_RANGE(1, 300)");
conn.close();
String[] args = { "-dir", dir, "-db", "utils", "-cipher", "XTEA", "-decrypt", "abc", "-quiet" };
ChangeFileEncryption.main(args);
args = new String[] { "-dir", dir, "-db", "utils", "-cipher", "AES", "-encrypt", "def", "-quiet" };
ChangeFileEncryption.main(args);
conn = DriverManager.getConnection(url + "/utils;CIPHER=AES", "sa", "def 123");
stat = conn.createStatement();
stat.execute("SELECT * FROM TEST");
new AssertThrows(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1) {
public void test() throws SQLException {
ChangeFileEncryption.main(new String[] {
"-dir", dir, "-db", "utils", "-cipher", "AES", "-decrypt", "def", "-quiet" });
}
};
conn.close();
args = new String[] { "-dir", dir, "-db", "utils", "-quiet" };
DeleteDbFiles.main(args);
}
private void testServer() throws SQLException {
Connection conn;
deleteDb("test");
Server tcpServer = Server.createTcpServer(
"-baseDir", getBaseDir(),
"-tcpPort", "9192",
"-tcpAllowOthers").start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", "");
conn.close();
tcpServer.stop();
Server.createTcpServer(
"-ifExists",
"-tcpPassword", "abc",
"-baseDir", getBaseDir(),
"-tcpPort", "9192").start();
// should not be able to create new db
try {
getConnection("jdbc:h2:tcp://localhost:9192/test2", "sa", "");
} catch (SQLException e) {
assertKnownException(e);
}
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", "");
conn.close();
new AssertThrows(ErrorCode.WRONG_USER_OR_PASSWORD) {
public void test() throws SQLException {
Server.shutdownTcpServer("tcp://localhost:9192", "", true, false);
}};
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", "");
// conn.close();
Server.shutdownTcpServer("tcp://localhost:9192", "abc", true, false);
// check that the database is closed
deleteDb("test");
// server must have been closed
assertThrows(ErrorCode.CONNECTION_BROKEN_1, this).
getConnection("jdbc:h2:tcp://localhost:9192/test", "sa", "");
JdbcUtils.closeSilently(conn);
// Test filesystem prefix and escape from baseDir
deleteDb("testSplit");
server = Server.createTcpServer(
"-baseDir", getBaseDir(),
"-tcpPort", "9192",
"-tcpAllowOthers").start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/split:testSplit", "sa", "");
conn.close();
assertThrows(ErrorCode.IO_EXCEPTION_1, this).
getConnection("jdbc:h2:tcp://localhost:9192/../test", "sa", "");
server.stop();
deleteDb("testSplit");
}
}