提交 5a766521 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 bc484005
......@@ -103,7 +103,7 @@ This database supports the following transaction isolation levels:
or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1
</li><li><b>Read Committed</b><br />
Read locks are released immediately.
Higer concurrency is possible when using this level.<br />
Higher concurrency is possible when using this level.<br />
This is the isolation level used for many database systems.<br />
To enable, execute the SQL statement 'SET LOCK_MODE 0'<br />
or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3
......
......@@ -37,7 +37,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / TODO (Build TODO)</h3><ul>
<li>Now PreparedStatement.setBigDecimal(..) can be called with an object of a derrived class
<li>PreparedStatement.getMetaData is now implemented.
</li><li>Now PreparedStatement.setBigDecimal(..) can be called with an object of a derived class
if the system property h2.allowBigDecimalExtensions is set to true.
</li><li>The default database name in the documentation is now jdbc:h2:~/test. Like this, the database
is stored in the user home directory (system property user.home). Of course storing the database
......
......@@ -75,7 +75,7 @@ After installing, you should get the following directory structure:
</tr>
<tr>
<td>service</td>
<td>Tools to run the database as a Windows Serivce</td>
<td>Tools to run the database as a Windows Service</td>
</tr>
<tr>
<td>src</td>
......
......@@ -44,6 +44,16 @@ public abstract class Command implements CommandInterface {
throw Message.getSQLException(Message.METHOD_ONLY_ALLOWED_FOR_QUERY);
}
public abstract LocalResult queryMeta() throws SQLException;
final public LocalResult getMetaDataLocal() throws SQLException {
return queryMeta();
}
final public ResultInterface getMetaData() throws SQLException {
return queryMeta();
}
public ResultInterface executeQuery(int maxrows, boolean scrollable) throws SQLException {
return executeQueryLocal(maxrows);
}
......@@ -86,7 +96,7 @@ public abstract class Command implements CommandInterface {
} else if (session.getAutoCommit()) {
session.commit(false);
} else if (Constants.MULTI_THREADED_KERNEL && session.getDatabase().getLockMode() == Constants.LOCK_MODE_READ_COMMITTED) {
session.unlockReadLocks();
session.unlockReadLocks();
}
if (trace.info()) {
long time = System.currentTimeMillis() - startTime;
......
......@@ -76,5 +76,9 @@ public class CommandContainer extends Command {
public boolean isReadOnly() {
return prepared.isReadOnly();
}
public LocalResult queryMeta() throws SQLException {
return prepared.queryMeta();
}
}
......@@ -16,4 +16,5 @@ public interface CommandInterface {
int executeUpdate() throws SQLException;
void close();
void cancel();
ResultInterface getMetaData() throws SQLException;
}
......@@ -58,5 +58,9 @@ public class CommandList extends Command {
public boolean isReadOnly() {
return false;
}
public LocalResult queryMeta() throws SQLException {
return command.queryMeta();
}
}
......@@ -30,6 +30,19 @@ public class CommandRemote implements CommandInterface {
private String sql;
private int paramCount;
public CommandRemote(SessionRemote session, ObjectArray transferList, String sql) throws SQLException {
this.transferList = transferList;
trace = session.getTrace();
this.sql = sql;
parameters = new ObjectArray();
prepare(session);
for(int i=0; i<paramCount; i++) {
parameters.add(new ParameterRemote(i));
}
// set session late because prepare might fail - in this case we don't need to close the object
this.session = session;
}
private void prepare(SessionRemote session) throws SQLException {
id = session.getNextId();
paramCount = 0;
......@@ -43,24 +56,11 @@ public class CommandRemote implements CommandInterface {
readonly = transfer.readBoolean();
paramCount = transfer.readInt();
} catch(IOException e) {
session.removeServer(i);
session.removeServer(i--);
}
}
}
public CommandRemote(SessionRemote session, ObjectArray transferList, String sql) throws SQLException {
this.transferList = transferList;
trace = session.getTrace();
this.sql = sql;
parameters = new ObjectArray();
prepare(session);
for(int i=0; i<paramCount; i++) {
parameters.add(new ParameterRemote(i));
}
// set session late because prepare might fail - in this case we don't need to close the object
this.session = session;
}
public boolean isQuery() {
return isQuery;
}
......@@ -69,6 +69,41 @@ public class CommandRemote implements CommandInterface {
return parameters;
}
public ResultInterface getMetaData() throws SQLException {
synchronized(session) {
session.checkClosed();
if(!isQuery) {
return null;
}
if(id <= session.getCurrentId() - Constants.SERVER_CACHED_OBJECTS) {
// object is too old - we need to prepare again
prepare(session);
}
int objectId = session.getNextId();
ResultRemote result = null;
for(int i=0; i<transferList.size(); i++) {
Transfer transfer = (Transfer) transferList.get(i);
try {
// TODO cluster: support load balance with values for each server / auto detect
session.traceOperation("COMMAND_GET_META_DATA", id);
transfer.writeInt(SessionRemote.COMMAND_GET_META_DATA).writeInt(id).writeInt(objectId);
session.done(transfer);
int columnCount = transfer.readInt();
if(result != null) {
result.close();
result = null;
}
result = new ResultRemote(session, transfer, objectId, columnCount, -1);
break;
} catch(IOException e) {
session.removeServer(i--);
}
}
session.autoCommitIfCluster();
return result;
}
}
public ResultInterface executeQuery(int maxRows, boolean scrollable) throws SQLException {
checkParameters();
synchronized(session) {
......@@ -104,7 +139,7 @@ public class CommandRemote implements CommandInterface {
break;
}
} catch(IOException e) {
session.removeServer(i);
session.removeServer(i--);
}
}
session.autoCommitIfCluster();
......@@ -132,7 +167,7 @@ public class CommandRemote implements CommandInterface {
updateCount = transfer.readInt();
autoCommit = transfer.readBoolean();
} catch(IOException e) {
session.removeServer(i);
session.removeServer(i--);
}
}
session.setAutoCommit(autoCommit);
......
......@@ -90,6 +90,8 @@ public abstract class Prepared {
throw Message.getSQLException(Message.METHOD_ONLY_ALLOWED_FOR_QUERY);
}
public abstract LocalResult queryMeta() throws SQLException;
public void setSQL(String sql) {
this.sql = sql;
}
......
......@@ -6,6 +6,7 @@ package org.h2.command.ddl;
import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.result.LocalResult;
public abstract class DefineCommand extends Prepared {
......@@ -21,4 +22,8 @@ public abstract class DefineCommand extends Prepared {
return false;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -18,6 +18,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.store.DiskFile;
import org.h2.store.FileLister;
import org.h2.store.LogFile;
......@@ -123,4 +124,8 @@ public class BackupCommand extends Prepared {
return false;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -30,12 +30,18 @@ public class Call extends Prepared {
public Call(Session session) {
super(session);
}
public LocalResult queryMeta() throws SQLException {
LocalResult result = new LocalResult(session, expressions, 1);
result.done();
return result;
}
public LocalResult query(int maxrows) throws SQLException {
setCurrentRowNumber(1);
Value v = value.getValue(session);
if(v.getType() == Value.RESULT_SET) {
return LocalResult.read(session, ((ValueResultSet)v).getResultSet());
return LocalResult.read(session, ((ValueResultSet)v).getResultSet(), maxrows);
} else if(v.getType() == Value.ARRAY) {
Value[] list = ((ValueArray)v).getList();
ObjectArray expr = new ObjectArray();
......
......@@ -10,6 +10,7 @@ import org.h2.command.Prepared;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.PlanItem;
......@@ -103,5 +104,9 @@ public class Delete extends Prepared {
public boolean isTransactional() {
return true;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -31,6 +31,10 @@ public class ExplainPlan extends Prepared {
public void prepare() throws SQLException {
command.prepare();
}
public LocalResult queryMeta() throws SQLException {
return query(-1);
}
public LocalResult query(int maxrows) throws SQLException {
// TODO rights: are rights required for explain?
......@@ -39,8 +43,10 @@ public class ExplainPlan extends Prepared {
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), null, column);
expressions.add(expr);
result = new LocalResult(session, expressions, 1);
String plan = command.getPlanSQL();
add(plan);
if(maxrows >= 0) {
String plan = command.getPlanSQL();
add(plan);
}
result.done();
return result;
}
......
......@@ -193,4 +193,8 @@ public class Insert extends Prepared {
return true;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -258,4 +258,8 @@ public class Merge extends Prepared {
return true;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -6,6 +6,7 @@ package org.h2.command.dml;
import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.result.LocalResult;
public class NoOperation extends Prepared {
......@@ -33,4 +34,8 @@ public class NoOperation extends Prepared {
return true;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -12,6 +12,7 @@ import java.sql.SQLException;
import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.util.ScriptReader;
import org.h2.util.StringUtils;
......@@ -67,4 +68,8 @@ public class RunScriptCommand extends ScriptBase {
this.charset = charset;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -26,7 +26,7 @@ import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.value.Value;
public class ScriptBase extends Prepared implements DataHandler {
public abstract class ScriptBase extends Prepared implements DataHandler {
private String cipher;
private byte[] key;
......
......@@ -94,14 +94,24 @@ public class ScriptCommand extends ScriptBase {
public void setDrop(boolean drop) {
this.drop = drop;
}
public LocalResult queryMeta() throws SQLException {
LocalResult result = createResult();
result.done();
return result;
}
private LocalResult createResult() {
ObjectArray cols = new ObjectArray();
cols.add(new ExpressionColumn(session.getDatabase(), null, new Column("SCRIPT", Value.STRING, 0, 0)));
return new LocalResult(session, cols, 1);
}
public LocalResult query(int maxrows) throws SQLException {
session.getUser().checkAdmin();
reset();
try {
ObjectArray cols = new ObjectArray();
cols.add(new ExpressionColumn(session.getDatabase(), null, new Column("SCRIPT", Value.STRING, 0, 0)));
result = new LocalResult(session, cols, 1);
result = createResult();
deleteStore();
openOutput();
if(out != null) {
......
......@@ -299,6 +299,12 @@ public class Select extends Query {
}
result.addRow(row);
}
public LocalResult queryMeta() throws SQLException {
LocalResult result = new LocalResult(session, expressions, visibleColumnCount);
result.done();
return result;
}
public LocalResult queryWithoutCache(int maxrows) throws SQLException {
if(maxrows != 0) {
......
......@@ -49,8 +49,6 @@ public class SelectUnion extends Query {
right = select;
}
public void setSQL(String sql) {
this.sql = sql;
}
......@@ -67,6 +65,14 @@ public class SelectUnion extends Query {
return values;
}
public LocalResult queryMeta() throws SQLException {
ObjectArray expressions = left.getExpressions();
int columnCount = left.getColumnCount();
LocalResult result = new LocalResult(session, expressions, columnCount);
result.done();
return result;
}
public LocalResult queryWithoutCache(int maxrows) throws SQLException {
if(maxrows != 0) {
if(limit != null) {
......
......@@ -18,6 +18,7 @@ import org.h2.engine.Setting;
import org.h2.expression.Expression;
import org.h2.expression.ValueExpression;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.schema.Schema;
import org.h2.table.Table;
import org.h2.tools.CompressTool;
......@@ -292,4 +293,8 @@ public class Set extends Prepared {
return false;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -10,6 +10,7 @@ import org.h2.command.Prepared;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
/**
......@@ -129,4 +130,8 @@ public class TransactionCommand extends Prepared {
this.transactionName = string;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -11,6 +11,7 @@ import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.table.Column;
import org.h2.table.PlanItem;
......@@ -161,4 +162,8 @@ public class Update extends Prepared {
return true;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -388,9 +388,10 @@ public class Database implements DataHandler {
// (maybe an application wants to write something into a database at shutdown time)
}
}
} catch(SQLException e) {
} catch(Throwable e) {
if(traceSystem != null) {
traceSystem.getTrace(Trace.DATABASE).error("opening " + databaseName, e);
traceSystem.close();
}
synchronized(this) {
closeOpenFilesAndUnlock();
......
......@@ -39,9 +39,12 @@ public class SessionRemote implements SessionInterface, DataHandler {
public static final int RESULT_CLOSE = 7;
public static final int COMMAND_COMMIT = 8;
public static final int CHANGE_ID = 9;
public static final int COMMAND_GET_META_DATA = 10;
public static final int STATUS_ERROR = 0;
public static final int STATUS_OK = 1;
public static final int STATUS_CLOSED = 2;
private TraceSystem traceSystem;
private Trace trace;
private ObjectArray transferList;
......@@ -119,7 +122,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
transfer.writeInt(SessionRemote.COMMAND_COMMIT);
done(transfer);
} catch(IOException e) {
removeServer(i);
removeServer(i--);
}
}
}
......
......@@ -950,16 +950,27 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
}
/**
* [Not supported] Gets the result set metadata of the query returned when the statement is executed.
* Gets the result set metadata of the query returned when the statement is executed.
* If this is not a query, this method returns null.
*
* @return null as the method is not supported
* @return the meta data or null if this is not a query
* @throws SQLException if this object is closed
*/
public ResultSetMetaData getMetaData() throws SQLException {
try {
debugCodeCall("getMetaData");
checkClosed();
return null;
ResultInterface result = command.getMetaData();
if(result == null) {
return null;
}
int id = getNextId(TraceObject.RESULT_SET_META_DATA);
if(debug()) {
debugCodeAssign("ResultSetMetaData", TraceObject.RESULT_SET_META_DATA, id);
debugCodeCall("getMetaData");
}
JdbcResultSetMetaData meta = new JdbcResultSetMetaData(null, this, result, session.getTrace(), id);
return meta;
} catch(Throwable e) {
throw logAndConvert(e);
}
......
......@@ -84,7 +84,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
debugCodeCall("getMetaData");
}
checkClosed();
JdbcResultSetMetaData meta = new JdbcResultSetMetaData(this, result, session.getTrace(), id);
JdbcResultSetMetaData meta = new JdbcResultSetMetaData(this, null, result, session.getTrace(), id);
return meta;
} catch(Throwable e) {
throw logAndConvert(e);
......@@ -2827,7 +2827,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
throw Message.getSQLException(Message.COLUMN_NOT_FOUND_1, columnName);
}
void checkColumnIndex(int columnIndex) throws SQLException {
private void checkColumnIndex(int columnIndex) throws SQLException {
checkClosed();
if (columnIndex < 1 || columnIndex > columnCount) {
throw Message.getInvalidValueException("" + columnIndex, "columnIndex");
......
......@@ -40,7 +40,7 @@ public class LocalResult implements ResultInterface {
private boolean isUpdateCount;
private int updateCount;
public static LocalResult read(Session session, ResultSet rs) throws SQLException {
public static LocalResult read(Session session, ResultSet rs, int maxrows) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
ObjectArray cols = new ObjectArray();
......@@ -57,7 +57,7 @@ public class LocalResult implements ResultInterface {
cols.add(expr);
}
LocalResult result = new LocalResult(session, cols, columnCount);
while (rs.next()) {
for(int i=0; (maxrows == 0 || i<maxrows) && rs.next(); i++) {
Value[] list = new Value[columnCount];
for (int j = 0; j < columnCount; j++) {
list[j] = DataType.readValue(session, rs, j + 1, types[j]);
......
......@@ -190,6 +190,20 @@ public class TcpServerThread implements Runnable {
transfer.writeInt(SessionRemote.STATUS_OK).flush();
break;
}
case SessionRemote.COMMAND_GET_META_DATA: {
int id = transfer.readInt();
int objectId = transfer.readInt();
Command command = (Command)cache.getObject(id, false);
LocalResult result = command.getMetaDataLocal();
cache.addObject(objectId, result);
int columnCount = result.getVisibleColumnCount();
transfer.writeInt(SessionRemote.STATUS_OK).writeInt(columnCount).writeInt(0);
for(int i=0; i<columnCount; i++) {
ResultColumn.writeColumn(transfer, result, i);
}
transfer.flush();
break;
}
case SessionRemote.COMMAND_EXECUTE_QUERY: {
int id = transfer.readInt();
int objectId = transfer.readInt();
......
......@@ -131,7 +131,7 @@ public class FunctionTable extends Table {
public LocalResult getResult(Session session) throws SQLException {
function.optimize(session);
ValueResultSet value = (ValueResultSet) function.getValue(session);
return LocalResult.read(session, value.getResultSet());
return LocalResult.read(session, value.getResultSet(), 0);
}
public long getMaxDataModificationId() {
......
......@@ -848,7 +848,7 @@ public class Recover implements DataHandler {
* INTERNAL
*/
public void handleInvalidChecksum() throws SQLException {
throw new SQLException("Invalid Checksum");
throw new SQLException("Invalid Checksum");
}
/**
......
......@@ -335,7 +335,7 @@ public class Server implements Runnable {
public Server start() throws SQLException {
service.start();
Thread t = new Thread(this);
t.setName(name);
t.setName(name + " (" + service.getURL() + ")");
t.start();
for(int i=1; i<64; i+=i) {
wait(i);
......
......@@ -94,7 +94,7 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
maybe another server server already
ResultSet.close() required for large query (before the database can be deleted, even if conn.close is called)?
make sure INDEX_LOOKUP_NEW = is true by default.
Test Console (batch, javaw, different platforms)
......
......@@ -70,20 +70,25 @@ public class TestCluster extends TestBase {
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9091,localhost:9092/test", "sa", "");
stat = conn.createStatement();
check(conn, len);
stat.execute("CREATE TABLE BOTH(ID INT)");
n1.stop();
stat.execute("CREATE TABLE A(ID INT)");
conn.close();
// n1.stop();
// n2.stop();
n2.stop();
// n1 = org.h2.tools.Server.startTcpServer(new String[]{"-tcpPort", "9091", "-baseDir", BASE_DIR + "/node1"});
n1 = org.h2.tools.Server.createTcpServer(new String[]{"-tcpPort", "9091", "-baseDir", BASE_DIR + "/node1"}).start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9091/test;CLUSTER=''", "sa", "");
check(conn, len);
conn.close();
n1.stop();
// n2 = org.h2.tools.Server.startTcpServer(new String[]{"-tcpPort", "9092", "-baseDir", BASE_DIR + "/node2"});
n2 = org.h2.tools.Server.createTcpServer(new String[]{"-tcpPort", "9092", "-baseDir", BASE_DIR + "/node2"}).start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9092/test;CLUSTER=''", "sa", "");
check(conn, len);
conn.createStatement().execute("SELECT * FROM A");
conn.close();
n2.stop();
}
......
......@@ -28,6 +28,7 @@ public class TestPreparedStatement extends TestBase {
deleteDb("preparedStatement");
Connection conn = getConnection("preparedStatement");
testPreparedStatementMetaData(conn);
testDate(conn);
testArray(conn);
testUUIDGeneratedKeys(conn);
......@@ -47,6 +48,18 @@ public class TestPreparedStatement extends TestBase {
conn.close();
}
private void testPreparedStatementMetaData(Connection conn) throws Exception {
PreparedStatement prep = conn.prepareStatement("select * from table(x int = ?, name varchar = ?)");
ResultSetMetaData meta = prep.getMetaData();
check(meta.getColumnCount(), 2);
check(meta.getColumnTypeName(1), "INTEGER");
check(meta.getColumnTypeName(2), "VARCHAR");
prep = conn.prepareStatement("call 1");
meta = prep.getMetaData();
check(meta.getColumnCount(), 1);
check(meta.getColumnTypeName(1), "INTEGER");
}
private void testArray(Connection conn) throws Exception {
PreparedStatement prep = conn.prepareStatement("select * from table(x int = ?) order by x");
prep.setObject(1, new Object[]{ new BigDecimal("1"), "2" });
......
......@@ -14,9 +14,11 @@ import java.io.PrintWriter;
import java.util.Date;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
......@@ -30,9 +32,17 @@ import org.h2.util.IOUtils;
public class TestRecover {
private Random random;
private static final String NODE = System.getProperty("h2.testRecoverPath", "1");
private static final String TEST_DIRECTORY = "/temp/db/data" + NODE;
private static final String BACKUP_DIRECTORY = "/temp/db/last";
private static final String NODE = System.getProperty("test.node", "");
private static final String DIR = System.getProperty("test.dir", "/temp/db");
// private static final String DIR = System.getProperty("test.dir", "/temp/derby");
// private static final String URL = System.getProperty("test.url", "jdbc:derby:/temp/derby/data/test;create=true");
// private static final String DRIVER = System.getProperty("test.driver", "org.apache.derby.jdbc.EmbeddedDriver");
private static final String TEST_DIRECTORY = DIR + "/data" + NODE;
private static final String BACKUP_DIRECTORY = DIR + "/last";
private static final String URL = System.getProperty("test.url", "jdbc:h2:" + TEST_DIRECTORY + "/test");
private static final String DRIVER = System.getProperty("test.driver", "org.h2.Driver");
public static void main(String[] args) throws Exception {
new TestRecover().runTest(args);
......@@ -157,22 +167,47 @@ public class TestRecover {
}
Connection openConnection() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:" + TEST_DIRECTORY + "/test", "sa", "sa");
Class.forName(DRIVER);
Connection conn = DriverManager.getConnection(URL, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID IDENTITY, NAME VARCHAR)");
try {
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
} catch(SQLException e) {
// ignore
}
return conn;
}
private void closeConnection(Connection conn) {
try {
conn.close();
} catch(SQLException e) {
// ignore
}
if(DRIVER.startsWith("org.apache.derby")) {
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch(SQLException e) {
// ignore
}
try {
Driver driver = (Driver)Class.forName(DRIVER).newInstance();
DriverManager.registerDriver(driver);
} catch(Exception e) {
e.printStackTrace();
}
}
}
private void runOneTest(int i) throws Exception {
Random random = new Random(i);
Connection conn = openConnection();
PreparedStatement prep = null;
while (true) {
for(int id=0; ; id++) {
boolean rollback = random.nextInt(10) == 1;
int len;
if (random.nextInt(10) == 1) {
len = random.nextInt(8000) * 2;
len = random.nextInt(100) * 2;
} else {
len = random.nextInt(2) * 2;
}
......@@ -184,15 +219,16 @@ public class TestRecover {
random.nextBytes(data);
int op = random.nextInt();
if (op % 100 == 0) {
conn.close();
closeConnection(conn);
conn = openConnection();
prep = null;
}
if(prep == null) {
prep = conn.prepareStatement("INSERT INTO TEST(NAME) VALUES(?)");
prep = conn.prepareStatement("INSERT INTO TEST(ID, NAME) VALUES(?, ?)");
conn.setAutoCommit(false);
}
prep.setString(1, "" + len);
prep.setInt(1, id);
prep.setString(2, "" + len);
prep.execute();
if (rollback) {
conn.rollback();
......@@ -218,14 +254,19 @@ public class TestRecover {
try {
conn = openConnection();
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
int max = 0;
while(rs.next()) {
int id = rs.getInt("ID");
String name = rs.getString("NAME");
int value = Integer.parseInt(name);
if(value % 2 == 1) {
throw new Exception("unexpected odd entry " + rs.getInt("ID"));
throw new Exception("unexpected odd entry " + id);
}
max = Math.max(max, id);
}
conn.close();
rs.close();
closeConnection(conn);
System.out.println("max rows: " + max);
return true;
} catch(Throwable t) {
t.printStackTrace();
......@@ -234,7 +275,7 @@ public class TestRecover {
} finally {
if(conn != null) {
try {
conn.close();
closeConnection(conn);
} catch(Throwable t2) {
t2.printStackTrace();
t2.printStackTrace(p);
......
......@@ -462,6 +462,7 @@ polish javaee resp xsi instances tomek realm xsd appended auth polski
signsoft intellibo jdo intelli middleware ute war sends snippet
gallery ord javaw weblica ltarget
initializers crashes openoffice member forgotten
oldest fat
### check those again:
populate slowly xacon inser maxbqualsize counter regards attaching official xatest
......@@ -476,9 +477,10 @@ isn truly toptier older meant pavel byteblob benchmarking regarding great unqual
wanted thoughts europeu astonished acceptable blobtable retrieval wasn demonstrate
incidentally brutal carefully pervasive testlob mydatetime antonio casqueiro sybase fourth
pad microsystems dullesopen rpad spot lpad ganelin sssz testabc pst dumping lots
### evaluatable > evaluable
chdh biz inventec
enclosing mostly dtp scrolls cars splitting replay incomplete automate
shorten
### evaluatable > evaluable
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论