提交 2493777f authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 caca6aaf
#! /bin/sh
#!/bin/sh
if [ -z "$JAVA_HOME" ] ; then
echo "Error: JAVA_HOME is not defined."
fi
if [ ! -f "bin/org/h2/build/Build.class" ] ; then
if [ ! -d "bin" ] ; then
md bin
mkdir bin
fi
javac -sourcepath src/tools -d bin src/tools/org/h2/build/*.java
fi
......
......@@ -943,6 +943,16 @@ Remote SSL/TLS connections are supported using the Java Secure Socket Extension
(SSLServerSocket / SSLSocket). By default, anonymous SSL is enabled.
The default cipher suite is <code>SSL_DH_anon_WITH_RC4_128_MD5</code>.
</p>
<p>
To use your own keystore, set the system properties <code>javax.net.ssl.keyStore</code> and
<code>javax.net.ssl.keyStorePassword</code> before starting the H2 server and client.
See also <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores">
Customizing the Default Key and Trust Stores, Store Types, and Store Passwords</a>
for more information.
</p>
<p>
To disable anonymous SSL, set the system property <code>h2.enableAnonymousSSL</code> to false.
</p>
<h3>HTTPS Connections</h3>
<p>
......
......@@ -3013,6 +3013,7 @@ public class Parser {
private Column parseColumnForTable(String columnName) throws SQLException {
Column column;
boolean isIdentity = false;
if (readIf("IDENTITY") || readIf("SERIAL")) {
column = new Column(columnName, Value.LONG);
column.setOriginalSQL("IDENTITY");
......@@ -3028,6 +3029,9 @@ public class Parser {
column.setNullable(true);
}
if (readIf("AS")) {
if (isIdentity) {
getSyntaxError();
}
Expression expr = readExpression();
column.setComputed(true, expr);
} else if (readIf("DEFAULT")) {
......
......@@ -87,6 +87,12 @@ public class SysProperties {
*/
public static final String ALLOWED_CLASSES = getStringSetting("h2.allowedClasses", "*");
/**
* System property <code>h2.enableAnonymousSSL</code> (default: true).<br />
* Comma separated list of class names or prefixes.
*/
public static final boolean ENABLE_ANONYMOUS_SSL = getBooleanSetting("h2.enableAnonymousSSL", true);
/**
* System property <code>h2.bindAddress</code> (default: *).<br />
* Comma separated list of class names or prefixes.
......
......@@ -249,6 +249,11 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
int k1 = rowData.getPos();
int k2 = compare.getPos();
if (k1 == k2) {
if (database.isMultiVersion()) {
int v1 = rowData.getVersion();
int v2 = compare.getVersion();
return v1 == v2 ? 0 : v1 < v2 ? 1 : -1;
}
return 0;
}
return k1 > k2 ? 1 : -1;
......
......@@ -165,7 +165,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
// create a row that only contains the key values
setChanged(session);
Row row = table.getTemplateRow();
row.setPos(r.getPos());
row.setPosAndVersion(r);
for (int i = 0; i < columns.length; i++) {
Column col = columns[i];
int idx = col.getColumnId();
......@@ -189,7 +189,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
SearchRow getSearchRow(Row row) {
SearchRow r = table.getTemplateSimpleRow(columns.length == 1);
r.setPos(row.getPos());
r.setPosAndVersion(row);
for (int j = 0; j < columns.length; j++) {
int idx = columns[j].getColumnId();
r.setValue(idx, row.getValue(idx));
......
......@@ -142,7 +142,11 @@ public class MultiVersionCursor implements Cursor {
}
int compare = index.compareRows(deltaRow, baseRow);
if (compare == 0) {
compare = index.compareKeys(deltaRow, baseRow);
// can't use compareKeys because the
// version would be compared as well
int k1 = deltaRow.getPos();
int k2 = baseRow.getPos();
compare = k1 == k2 ? 0 : k1 > k2 ? 1 : -1;
}
if (compare == 0) {
if (isDeleted) {
......@@ -170,9 +174,6 @@ public class MultiVersionCursor implements Cursor {
needNewBase = true;
return true;
}
if (!isDeleted) {
throw Message.getInternalError();
}
onBase = false;
needNewDelta = true;
return true;
......
......@@ -120,15 +120,17 @@ public class MultiVersionIndex implements Index {
public boolean needRebuild() {
return base.needRebuild();
}
private boolean removeIfExists(Session session, Row row) throws SQLException {
// maybe it was inserted by the same session just before
Cursor c = delta.find(session, row, row);
while (c.next()) {
Row r = c.get();
if (r.getPos() == row.getPos()) {
if (r == row || table.getScanIndex(session).compareRows(r, row) == 0) {
delta.remove(session, row);
if (r.getPos() == row.getPos() && r.getVersion() == row.getVersion()) {
if (r != row && table.getScanIndex(session).compareRows(r, row) != 0) {
row.setVersion(r.getVersion() + 1);
} else {
delta.remove(session, r);
return true;
}
}
......@@ -146,7 +148,7 @@ public class MultiVersionIndex implements Index {
}
}
}
public void remove(Session session) throws SQLException {
synchronized (sync) {
base.remove(session);
......
......@@ -114,6 +114,7 @@ public class ScanIndex extends BaseIndex {
}
storage.addRecord(session, row, Storage.ALLOCATE_POS);
} else {
// in-memory
if (firstFree == -1) {
int key = rows.size();
row.setPos(key);
......@@ -171,6 +172,7 @@ public class ScanIndex extends BaseIndex {
}
}
} else {
// in-memory
Row free = new Row(null, 0);
free.setPos(firstFree);
int key = row.getPos();
......
......@@ -29,7 +29,7 @@ import org.h2.message.TraceObject;
/*## Java 1.6 begin ##
import org.h2.message.Message;
//## Java 1.4 end ##
## Java 1.6 end ##*/
/**
* A data source for H2 database connections. It is a factory for XAConnection
......
......@@ -19,11 +19,25 @@ public class Row extends Record implements SearchRow {
public static final int MEMORY_CALCULATE = -1;
private final Value[] data;
private final int memory;
private int version;
public Row(Value[] data, int memory) {
this.data = data;
this.memory = memory;
}
public void setPosAndVersion(SearchRow row) {
setPos(row.getPos());
setVersion(row.getVersion());
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public Row(Row old) {
this.data = old.data;
......@@ -79,6 +93,9 @@ public class Row extends Record implements SearchRow {
StringBuffer buff = new StringBuffer(data.length * 5);
buff.append("( /* pos:");
buff.append(getPos());
if (version != 0) {
buff.append(" v:" + version);
}
if (getDeleted()) {
buff.append(" deleted");
}
......
......@@ -44,11 +44,12 @@ public class RowList {
}
private void writeRow(DataPage buff, Row r) throws SQLException {
buff.checkCapacity(1 + buff.getIntLen() * 6);
buff.checkCapacity(1 + buff.getIntLen() * 7);
buff.writeByte((byte) 1);
buff.writeInt(r.getMemorySize());
buff.writeInt(r.getColumnCount());
buff.writeInt(r.getPos());
buff.writeInt(r.getVersion());
buff.writeInt(r.getDeleted() ? 1 : 0);
buff.writeInt(r.getSessionId());
buff.writeInt(r.getStorageId());
......@@ -143,6 +144,7 @@ public class RowList {
int memory = buff.readInt();
int columnCount = buff.readInt();
int pos = buff.readInt();
int version = buff.readInt();
if (readUncached) {
pos = 0;
}
......@@ -170,6 +172,7 @@ public class RowList {
}
Row row = new Row(values, memory);
row.setPos(pos);
row.setVersion(version);
row.setDeleted(deleted);
row.setSessionId(sessionId);
row.setStorageId(storageId);
......
......@@ -14,11 +14,11 @@ import org.h2.value.Value;
public interface SearchRow {
/**
* Get the position of the row in the data file.
* Get the column count.
*
* @return the position
* @return the column count
*/
int getPos();
int getColumnCount();
/**
* Get the value for the column
......@@ -28,13 +28,6 @@ public interface SearchRow {
*/
Value getValue(int index);
/**
* Get the column count.
*
* @return the column count
*/
int getColumnCount();
/**
* Set the value for given column
*
......@@ -43,6 +36,13 @@ public interface SearchRow {
*/
void setValue(int index, Value v);
/**
* Set the position and version to match another row.
*
* @param old the other row.
*/
void setPosAndVersion(SearchRow old);
/**
* Set the position (where the row is stored in the data file).
*
......@@ -50,4 +50,18 @@ public interface SearchRow {
*/
void setPos(int pos);
/**
* Get the position of the row in the data file.
*
* @return the position
*/
int getPos();
/**
* Get the version of the row.
*
* @return the version
*/
int getVersion();
}
......@@ -13,6 +13,7 @@ import org.h2.value.Value;
public class SimpleRow implements SearchRow {
private int pos;
private int version;
private Value[] data;
public SimpleRow(Value[] data) {
......@@ -30,6 +31,15 @@ public class SimpleRow implements SearchRow {
public void setPos(int pos) {
this.pos = pos;
}
public void setPosAndVersion(SearchRow row) {
pos = row.getPos();
version = row.getVersion();
}
public int getVersion() {
return version;
}
public void setValue(int i, Value v) {
data[i] = v;
......
......@@ -13,6 +13,7 @@ import org.h2.value.Value;
public class SimpleRowValue implements SearchRow {
private int pos;
private int version;
private int index;
private int virtualColumnCount;
private Value data;
......@@ -20,6 +21,19 @@ public class SimpleRowValue implements SearchRow {
public SimpleRowValue(int columnCount) {
this.virtualColumnCount = columnCount;
}
public void setPosAndVersion(SearchRow row) {
pos = row.getPos();
version = row.getVersion();
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public int getColumnCount() {
return virtualColumnCount;
......
......@@ -28,6 +28,7 @@ import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
......@@ -45,8 +46,6 @@ public class SecureSocketFactory {
private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
public static final String KEYSTORE_PASSWORD = "h2pass";
// TODO security / SSL: need a way to disable anonymous ssl
private static final boolean ENABLE_ANONYMOUS_SSL = true;
private static SecureSocketFactory factory;
private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5";
......@@ -67,7 +66,7 @@ public class SecureSocketFactory {
setKeystore();
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket secureSocket = (SSLSocket) f.createSocket(address, port);
if (ENABLE_ANONYMOUS_SSL) {
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
......@@ -89,7 +88,7 @@ public class SecureSocketFactory {
} else {
secureSocket = (SSLServerSocket) f.createServerSocket(port, 0, bindAddress);
}
if (ENABLE_ANONYMOUS_SSL) {
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
......
......@@ -86,9 +86,9 @@ public class Backup extends Tool {
/**
* Backs up database files.
*
* @param zipFileName the name of the backup file
* @param directory the directory name
* @param db the database name (null if there is only one database)
* @param zipFileName the name of the target backup file (including path)
* @param directory the source directory name
* @param db the source database name (null if there is only one database)
* @param quiet don't print progress information
* @throws SQLException
*/
......
......@@ -159,6 +159,17 @@ java org.h2.test.TestAll timer
/*
Flux
Java Job Scheduler. File Transfer. Workflow. BPM.
http://www.fluxcorp.com/
No database files found > in directory " + for a database called .
Has anyone had difficulty with Open Office Base and UUID type fields
in H2? I think that I may not be able to view table data that has
UUID data in it. Any ideas?
test case for out of memory (try to corrupt the database using out of memory)
analyzer configuration option for the fulltext search
......@@ -216,11 +227,13 @@ Multi version concurrency (MVCC): when a row was updated,
not committed
Calling SHUTDOWN on one connection and starting a query on
another connection concurrently could result in a Java level deadlock.
New system property h2.enableAnonymousSSL (default: true) to enable
anonymous SSL connections.
Roadmap:
*/
if (args.length > 0) {
if ("crash".equals(args[0])) {
test.endless = true;
......@@ -417,7 +430,6 @@ Roadmap:
* Run all tests with the current settings.
*/
private void test() throws Exception {
System.out.println();
System.out.println("Test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc + " deleteIndex:" + deleteIndex);
beforeTest();
......
......@@ -502,7 +502,7 @@ public class TestCases extends TestBase {
conn.createStatement().execute("INSERT INTO TEST_SEQ(NAME) VALUES('Hi')");
ResultSet rs = conn.createStatement().executeQuery("CALL IDENTITY()");
rs.next();
check(rs.getInt(1), 1);
check(1, rs.getInt(1));
conn.createStatement().execute("SELECT * FROM TEST2");
conn.createStatement().execute("SELECT * FROM TEST_B");
conn.createStatement().execute("ALTER TABLE TEST_B RENAME TO TEST_B2");
......@@ -512,7 +512,7 @@ public class TestCases extends TestBase {
conn.createStatement().execute("INSERT INTO TEST_SEQ(NAME) VALUES('World')");
rs = conn.createStatement().executeQuery("CALL IDENTITY()");
rs.next();
check(rs.getInt(1), 2);
check(2, rs.getInt(1));
conn.close();
}
......
......@@ -85,32 +85,6 @@ public class TestMvcc1 extends TestBase {
s2 = c2.createStatement();
c1.setAutoCommit(false);
c2.setAutoCommit(false);
// it should not be possible to drop a table
// when an uncommitted transaction changed something
s1.execute("create table test(id int primary key)");
s1.execute("insert into test values(1)");
try {
s2.execute("drop table test");
error();
} catch (SQLException e) {
// lock timeout expected
checkNotGeneralException(e);
}
c1.rollback();
s2.execute("drop table test");
c2.rollback();
// table scan problem
s1.execute("create table test(id int, name varchar)");
s1.execute("insert into test values(1, 'A'), (2, 'B')");
c1.commit();
test(s1, "select count(*) from test where name<>'C'", "2");
s2.execute("update test set name='B2' where id=2");
test(s1, "select count(*) from test where name<>'C'", "2");
c2.commit();
s2.execute("drop table test");
c2.rollback();
// update same key problem
s1.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR, PRIMARY KEY(ID))");
......@@ -123,7 +97,7 @@ public class TestMvcc1 extends TestBase {
s1.execute("DROP TABLE TEST");
c1.commit();
c2.commit();
// referential integrity problem
s1.execute("create table a (id integer identity not null, code varchar(10) not null, primary key(id))");
s1.execute("create table b (name varchar(100) not null, a integer, primary key(name), foreign key(a) references a(id))");
......@@ -139,6 +113,32 @@ public class TestMvcc1 extends TestBase {
s1.execute("drop table a, b");
c2.commit();
// it should not be possible to drop a table
// when an uncommitted transaction changed something
s1.execute("create table test(id int primary key)");
s1.execute("insert into test values(1)");
try {
s2.execute("drop table test");
error();
} catch (SQLException e) {
// lock timeout expected
checkNotGeneralException(e);
}
c1.rollback();
s2.execute("drop table test");
c2.rollback();
// table scan problem
s1.execute("create table test(id int, name varchar)");
s1.execute("insert into test values(1, 'A'), (2, 'B')");
c1.commit();
test(s1, "select count(*) from test where name<>'C'", "2");
s2.execute("update test set name='B2' where id=2");
test(s1, "select count(*) from test where name<>'C'", "2");
c2.commit();
s2.execute("drop table test");
c2.rollback();
// select for update should do an exclusive lock, even with mvcc
s1.execute("create table test(id int primary key, name varchar(255))");
s1.execute("insert into test values(1, 'y')");
......
......@@ -17,6 +17,7 @@ import org.h2.test.TestBase;
public class TestMvcc3 extends TestBase {
public void test() throws Exception {
testSequence();
if (!config.mvcc) {
return;
}
......@@ -34,6 +35,32 @@ public class TestMvcc3 extends TestBase {
check(1, rs.getInt(1));
conn.close();
}
private void testSequence() throws Exception {
if (config.memory) {
return;
}
deleteDb("mvcc3");
Connection conn;
ResultSet rs;
conn = getConnection("mvcc3");
conn.createStatement().execute("create sequence abc");
conn.close();
conn = getConnection("mvcc3");
rs = conn.createStatement().executeQuery("call abc.nextval");
rs.next();
check(1, rs.getInt(1));
conn.close();
conn = getConnection("mvcc3");
rs = conn.createStatement().executeQuery("call abc.currval");
rs.next();
check(1, rs.getInt(1));
conn.close();
}
}
......
......@@ -5,6 +5,7 @@
*/
package org.h2.test.unit;
import java.lang.reflect.Method;
import java.sql.Timestamp;
/**
......@@ -37,7 +38,43 @@ public class SelfDestructor extends Thread {
}
}
String time = new Timestamp(System.currentTimeMillis()).toString();
System.out.println(time + " Killing the process after " + minutes + " minutes");
System.out.println(time + " Killing the process after " + minutes + " minute(s)");
try {
int activeCount = Thread.activeCount();
Thread[] threads = new Thread[activeCount + 100];
int len = Thread.enumerate(threads);
for (int i = 0; i < len; i++) {
Thread t = threads[i];
String threadName = "Thread #" + i + ": " + t.getName();
System.out.println(threadName);
}
System.out.flush();
try {
Thread.sleep(1000);
} catch (Exception e) {
// ignore
}
Method stop = Thread.class.getMethod("stop", new Class[]{Throwable.class});
for (int i = 0; i < len; i++) {
Thread t = threads[i];
String threadName = "Thread #" + i + ": " + t.getName();
Error e = new Error(threadName);
if (t != Thread.currentThread()) {
stop.invoke(t, new Object[]{e});
t.interrupt();
}
}
} catch (Throwable t) {
t.printStackTrace();
// ignore
}
try {
Thread.sleep(1000);
} catch (Exception e) {
// ignore
}
System.out.println("Killing the process now");
Runtime.getRuntime().halt(1);
}
};
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论