提交 9549cb57 authored 作者: Thomas Mueller's avatar Thomas Mueller

Improved MVStore tests.

上级 69799fc8
...@@ -31,7 +31,6 @@ import java.util.LinkedList; ...@@ -31,7 +31,6 @@ import java.util.LinkedList;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.mvstore.db.MVTableEngine;
import org.h2.store.FileLock; import org.h2.store.FileLock;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.test.utils.ProxyCodeGenerator; import org.h2.test.utils.ProxyCodeGenerator;
...@@ -266,8 +265,7 @@ public abstract class TestBase { ...@@ -266,8 +265,7 @@ public abstract class TestBase {
} else { } else {
url = name; url = name;
} }
int test; // url = addOption(url, "DEFAULT_TABLE_ENGINE", "org.h2.mvstore.db.MVTableEngine");
// url = addOption(url, "DEFAULT_TABLE_ENGINE", MVTableEngine.class.getName());
if (!config.memory) { if (!config.memory) {
if (config.smallLog && admin) { if (config.smallLog && admin) {
url = addOption(url, "MAX_LOG_SIZE", "1"); url = addOption(url, "MAX_LOG_SIZE", "1");
......
...@@ -32,8 +32,8 @@ public class SequenceMap extends MVMap<Long, Long> { ...@@ -32,8 +32,8 @@ public class SequenceMap extends MVMap<Long, Long> {
super(null, null); super(null, null);
} }
public void open(MVStore store, HashMap<String, String> config) { public void init(MVStore store, HashMap<String, String> config) {
super.open(store, config); super.init(store, config);
setReadOnly(true); setReadOnly(true);
} }
......
...@@ -40,6 +40,7 @@ public class TestMVStore extends TestBase { ...@@ -40,6 +40,7 @@ public class TestMVStore extends TestBase {
public void test() throws Exception { public void test() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true); FileUtils.deleteRecursive(getBaseDir(), true);
testRecreateMap();
testRenameMapRollback(); testRenameMapRollback();
testCustomMapType(); testCustomMapType();
testCacheSize(); testCacheSize();
...@@ -72,6 +73,22 @@ public class TestMVStore extends TestBase { ...@@ -72,6 +73,22 @@ public class TestMVStore extends TestBase {
testSimple(); testSimple();
} }
private void testRecreateMap() {
String fileName = getBaseDir() + "/testRecreateMap.h3";
FileUtils.delete(fileName);
MVStore s = openStore(fileName);
MVMap<Integer, Integer> m = s.openMap("test");
m.put(1, 1);
s.store();
m.removeMap();
s.store();
s.close();
s = openStore(fileName);
m = s.openMap("test");
assertNull(m.get(1));
s.close();
}
private void testRenameMapRollback() { private void testRenameMapRollback() {
MVStore s = openStore(null); MVStore s = openStore(null);
MVMap<Integer, Integer> map; MVMap<Integer, Integer> map;
...@@ -546,6 +563,13 @@ public class TestMVStore extends TestBase { ...@@ -546,6 +563,13 @@ public class TestMVStore extends TestBase {
mOld = m.openVersion(old3); mOld = m.openVersion(old3);
assertEquals("Hallo", mOld.get("1")); assertEquals("Hallo", mOld.get("1"));
assertEquals("Welt", mOld.get("2")); assertEquals("Welt", mOld.get("2"));
try {
m.openVersion(-3);
fail();
} catch (IllegalArgumentException e) {
// expected
}
s.close(); s.close();
} }
......
...@@ -5,13 +5,18 @@ ...@@ -5,13 +5,18 @@
*/ */
package org.h2.test.store; package org.h2.test.store;
import java.math.BigDecimal;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Random; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.mvstore.db.MVTableEngine; import org.h2.mvstore.db.MVTableEngine;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.Task;
/** /**
* Tests the MVStore in a database. * Tests the MVStore in a database.
...@@ -28,83 +33,239 @@ public class TestMVTableEngine extends TestBase { ...@@ -28,83 +33,239 @@ public class TestMVTableEngine extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testCase(); testReuseDiskSpace();
testDataTypes();
testLocking();
testSimple(); testSimple();
} }
private void testReuseDiskSpace() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
String dbName = "mvstore" +
";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
Connection conn;
Statement stat;
long maxSizeHalf = 0;
for (int i = 0; i < 10; i++) {
conn = getConnection(dbName);
for (MVTableEngine.Store s : MVTableEngine.getStores()) {
s.getStore().setRetentionTime(0);
}
stat = conn.createStatement();
stat.execute("create table test(id int primary key, data varchar)");
stat.execute("insert into test select x, space(1000) from system_range(1, 1000)");
stat.execute("drop table test");
conn.close();
long size = FileUtils.size(getBaseDir() + "/mvstore"
+ Constants.SUFFIX_MV_FILE);
if (i < 6) {
maxSizeHalf = Math.max(size, maxSizeHalf);
} else if (size > maxSizeHalf) {
fail("size: " + size + " max: " + maxSizeHalf);
}
}
}
private void testCase() throws Exception { private void testDataTypes() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true); FileUtils.deleteRecursive(getBaseDir(), true);
deleteDb("cases"); String dbName = "mvstore" +
Connection conn = getConnection("cases"); ";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
Connection conn = getConnection(dbName);
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, " +
"vc varchar," +
"ch char(10)," +
"bo boolean," +
"by tinyint," +
"sm smallint," +
"bi bigint," +
"de decimal," +
"re real,"+
"do double," +
"ti time," +
"da date," +
"ts timestamp," +
"bin binary," +
"uu uuid," +
"bl blob," +
"cl clob)");
stat.execute("insert into test values(1000, '', '', null, 0, 0, 0, "
+ "9, 2, 3, '10:00:00', '2001-01-01', "
+ "'2010-10-10 10:10:10', x'00', 0, x'b1', 'clob')");
stat.execute("insert into test values(1, 'vc', 'ch', true, 8, 16, 64, "
+ "123.00, 64.0, 32.0, '10:00:00', '2001-01-01', "
+ "'2010-10-10 10:10:10', x'00', 0, x'b1', 'clob')");
stat.execute("insert into test values(-1, 'quite a long string \u1234 \u00ff', 'ch', false, -8, -16, -64, "
+ "0, 0, 0, '10:00:00', '2001-01-01', "
+ "'2010-10-10 10:10:10', SECURE_RAND(100), 0, x'b1', 'clob')");
stat.execute("insert into test values(-1000, space(1000), 'ch', false, -8, -16, -64, "
+ "1, 1, 1, '10:00:00', '2001-01-01', "
+ "'2010-10-10 10:10:10', SECURE_RAND(100), 0, x'b1', 'clob')");
if (!config.memory) {
conn.close();
conn = getConnection(dbName);
stat = conn.createStatement();
}
ResultSet rs; ResultSet rs;
rs = stat.executeQuery("select * from test order by id desc");
rs.next();
assertEquals(1000, rs.getInt(1));
assertEquals("", rs.getString(2));
assertEquals("", rs.getString(3));
assertFalse(rs.getBoolean(4));
assertEquals(0, rs.getByte(5));
assertEquals(0, rs.getShort(6));
assertEquals(0, rs.getLong(7));
assertEquals("9", rs.getBigDecimal(8).toString());
assertEquals(2d, rs.getDouble(9));
assertEquals(3d, rs.getFloat(10));
assertEquals("10:00:00", rs.getString(11));
assertEquals("2001-01-01", rs.getString(12));
assertEquals("2010-10-10 10:10:10.0", rs.getString(13));
assertEquals(1, rs.getBytes(14).length);
assertEquals("00000000-0000-0000-0000-000000000000", rs.getString(15));
assertEquals(1, rs.getBytes(16).length);
assertEquals("clob", rs.getString(17));
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("vc", rs.getString(2));
assertEquals("ch", rs.getString(3));
assertTrue(rs.getBoolean(4));
assertEquals(8, rs.getByte(5));
assertEquals(16, rs.getShort(6));
assertEquals(64, rs.getLong(7));
assertEquals("123.00", rs.getBigDecimal(8).toString());
assertEquals(64d, rs.getDouble(9));
assertEquals(32d, rs.getFloat(10));
assertEquals("10:00:00", rs.getString(11));
assertEquals("2001-01-01", rs.getString(12));
assertEquals("2010-10-10 10:10:10.0", rs.getString(13));
assertEquals(1, rs.getBytes(14).length);
assertEquals("00000000-0000-0000-0000-000000000000", rs.getString(15));
assertEquals(1, rs.getBytes(16).length);
assertEquals("clob", rs.getString(17));
rs.next();
assertEquals(-1, rs.getInt(1));
assertEquals("quite a long string \u1234 \u00ff", rs.getString(2));
assertEquals("ch", rs.getString(3));
assertFalse(rs.getBoolean(4));
assertEquals(-8, rs.getByte(5));
assertEquals(-16, rs.getShort(6));
assertEquals(-64, rs.getLong(7));
assertEquals("0", rs.getBigDecimal(8).toString());
assertEquals(0.0d, rs.getDouble(9));
assertEquals(0.0d, rs.getFloat(10));
assertEquals("10:00:00", rs.getString(11));
assertEquals("2001-01-01", rs.getString(12));
assertEquals("2010-10-10 10:10:10.0", rs.getString(13));
assertEquals(100, rs.getBytes(14).length);
assertEquals("00000000-0000-0000-0000-000000000000", rs.getString(15));
assertEquals(1, rs.getBytes(16).length);
assertEquals("clob", rs.getString(17));
rs.next();
assertEquals(-1000, rs.getInt(1));
assertEquals(1000, rs.getString(2).length());
assertEquals("ch", rs.getString(3));
assertFalse(rs.getBoolean(4));
assertEquals(-8, rs.getByte(5));
assertEquals(-16, rs.getShort(6));
assertEquals(-64, rs.getLong(7));
assertEquals("1", rs.getBigDecimal(8).toString());
assertEquals(1.0d, rs.getDouble(9));
assertEquals(1.0d, rs.getFloat(10));
assertEquals("10:00:00", rs.getString(11));
assertEquals("2001-01-01", rs.getString(12));
assertEquals("2010-10-10 10:10:10.0", rs.getString(13));
assertEquals(100, rs.getBytes(14).length);
assertEquals("00000000-0000-0000-0000-000000000000", rs.getString(15));
assertEquals(1, rs.getBytes(16).length);
assertEquals("clob", rs.getString(17));
Random random = new Random(1); stat.execute("drop table test");
int len = getSize(50, 500);
for (int i = 0; i < len; i++) { stat.execute("create table test(id int, obj object, rs result_set, arr array, ig varchar_ignorecase)");
stat.execute("drop table if exists test"); PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?, ?, ?, ?)");
stat.execute("create table test(x int)"); prep.setInt(1, 1);
if (random.nextBoolean()) { prep.setObject(2, new java.lang.AssertionError());
int count = random.nextBoolean() ? 1 : 1 + random.nextInt(len); prep.setObject(3, stat.executeQuery("select 1 from dual"));
if (count > 0) { prep.setObject(4, new Object[]{1, 2});
stat.execute("insert into test select null from system_range(1, " + count + ")"); prep.setObject(5, "test");
} prep.execute();
} prep.setInt(1, 1);
int maxExpected = -1; prep.setObject(2, new java.lang.AssertionError());
int minExpected = -1; prep.setObject(3, stat.executeQuery("select 1 from dual"));
if (random.nextInt(10) != 1) { prep.setObject(4, new Object[]{new BigDecimal(new String(new char[1000]).replace((char) 0, '1'))});
minExpected = 1; prep.setObject(5, "test");
maxExpected = 1 + random.nextInt(len); prep.execute();
stat.execute("insert into test select x from system_range(1, " + maxExpected + ")"); if (!config.memory) {
} conn.close();
String sql = "create index idx on test(x"; conn = getConnection(dbName);
if (random.nextBoolean()) { stat = conn.createStatement();
sql += " desc";
}
if (random.nextBoolean()) {
if (random.nextBoolean()) {
sql += " nulls first";
} else {
sql += " nulls last";
}
}
sql += ")";
stat.execute(sql);
rs = stat.executeQuery("select min(x), max(x) from test");
rs.next();
int min = rs.getInt(1);
if (rs.wasNull()) {
min = -1;
}
int max = rs.getInt(2);
if (rs.wasNull()) {
max = -1;
}
assertEquals(minExpected, min);
assertEquals(maxExpected, max);
} }
stat.execute("select * from test");
stat.execute("drop table test");
conn.close(); conn.close();
}
private void testLocking() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
String dbName = "mvstore" +
";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
Connection conn = getConnection(dbName);
Statement stat = conn.createStatement();
stat.execute("set lock_timeout 1000");
stat.execute("create table a(id int primary key, name varchar)");
stat.execute("create table b(id int primary key, name varchar)");
Connection conn1 = getConnection(dbName);
final Statement stat1 = conn1.createStatement();
stat1.execute("set lock_timeout 1000");
conn.setAutoCommit(false);
conn1.setAutoCommit(false);
stat.execute("insert into a values(1, 'Hello')");
stat1.execute("insert into b values(1, 'Hello')");
Task t = new Task() {
@Override
public void call() throws Exception {
stat1.execute("insert into a values(2, 'World')");
}
};
t.execute();
try {
stat.execute("insert into b values(2, 'World')");
throw t.getException();
} catch (SQLException e) {
assertEquals(e.toString(), ErrorCode.DEADLOCK_1, e.getErrorCode());
}
conn1.close();
conn.close();
} }
private void testSimple() throws Exception { private void testSimple() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true); FileUtils.deleteRecursive(getBaseDir(), true);
Connection conn = getConnection("mvstore"); String dbName = "mvstore" +
";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
Connection conn = getConnection(dbName);
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
// create table test(id int, name varchar) engine "org.h2.mvstore.db.MVStoreTableEngine" // create table test(id int, name varchar) engine "org.h2.mvstore.db.MVStoreTableEngine"
stat.execute("create table test(id int primary key, name varchar) engine \"" + stat.execute("create table test(id int primary key, name varchar)");
MVTableEngine.class.getName() + "\"");
stat.execute("insert into test values(1, 'Hello'), (2, 'World')"); stat.execute("insert into test values(1, 'Hello'), (2, 'World')");
ResultSet rs = stat.executeQuery("select * from test"); ResultSet rs = stat.executeQuery("select *, _rowid_ from test");
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1, rs.getInt(1)); assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2)); assertEquals("Hello", rs.getString(2));
conn.close(); assertEquals(1, rs.getInt(3));
if (!config.memory) {
conn.close();
conn = getConnection(dbName);
stat = conn.createStatement();
}
conn = getConnection("mvstore");
stat = conn.createStatement();
rs = stat.executeQuery("select * from test order by id"); rs = stat.executeQuery("select * from test order by id");
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1, rs.getInt(1)); assertEquals(1, rs.getInt(1));
...@@ -114,6 +275,28 @@ public class TestMVTableEngine extends TestBase { ...@@ -114,6 +275,28 @@ public class TestMVTableEngine extends TestBase {
assertEquals("World", rs.getString(2)); assertEquals("World", rs.getString(2));
assertFalse(rs.next()); assertFalse(rs.next());
stat.execute("create unique index idx_name on test(name)");
rs = stat.executeQuery("select * from test where name = 'Hello' order by name");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
assertFalse(rs.next());
try {
stat.execute("insert into test(id, name) values(10, 'Hello')");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.DUPLICATE_KEY_1, e.getErrorCode());
}
rs = stat.executeQuery("select min(id), max(id), min(name), max(name) from test");
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals(2, rs.getInt(2));
assertEquals("Hello", rs.getString(3));
assertEquals("World", rs.getString(4));
assertFalse(rs.next());
stat.execute("delete from test where id = 2"); stat.execute("delete from test where id = 2");
rs = stat.executeQuery("select * from test order by id"); rs = stat.executeQuery("select * from test order by id");
assertTrue(rs.next()); assertTrue(rs.next());
...@@ -121,15 +304,42 @@ public class TestMVTableEngine extends TestBase { ...@@ -121,15 +304,42 @@ public class TestMVTableEngine extends TestBase {
assertEquals("Hello", rs.getString(2)); assertEquals("Hello", rs.getString(2));
assertFalse(rs.next()); assertFalse(rs.next());
stat.execute("create index idx_name on test(name)"); stat.execute("alter table test add column firstName varchar");
rs = stat.executeQuery("select * from test where name = 'Hello'"); rs = stat.executeQuery("select * from test where name = 'Hello'");
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1, rs.getInt(1)); assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2)); assertEquals("Hello", rs.getString(2));
assertFalse(rs.next()); assertFalse(rs.next());
conn.close(); if (!config.memory) {
} conn.close();
conn = getConnection(dbName);
stat = conn.createStatement();
}
rs = stat.executeQuery("select * from test order by id");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
assertFalse(rs.next());
stat.execute("truncate table test");
rs = stat.executeQuery("select * from test order by id");
assertFalse(rs.next());
rs = stat.executeQuery("select count(*) from test");
rs.next();
assertEquals(0, rs.getInt(1));
stat.execute("insert into test(id) select x from system_range(1, 3000)");
rs = stat.executeQuery("select count(*) from test");
rs.next();
assertEquals(3000, rs.getInt(1));
try {
stat.execute("insert into test(id) values(1)");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.DUPLICATE_KEY_1, e.getErrorCode());
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论