提交 390b9472 authored 作者: Thomas Mueller's avatar Thomas Mueller

Remove unused code.

上级 798a5049
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The file system abstraction no longer throws SQL exceptions. <ul><li>Hash indexes now are only used for single column indexes.
</li><li>The cache types WEAK_* and TQ are no longer supported.
</li><li>The file system abstraction no longer throws SQL exceptions.
</li><li>DatabaseEventListener.diskSpaceIsLow has changed. </li><li>DatabaseEventListener.diskSpaceIsLow has changed.
</li><li>The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions. </li><li>The CompressTool no longer throw as SQL exceptions. Instead, it throws runtime exceptions.
</li><li>SimpleResultSet.addColumn and addRow now can throw a IllegalStateException </li><li>SimpleResultSet.addColumn and addRow now can throw a IllegalStateException
......
...@@ -1749,7 +1749,12 @@ public class Database implements DataHandler { ...@@ -1749,7 +1749,12 @@ public class Database implements DataHandler {
* executing the SQL statement CHECKPOINT SYNC. * executing the SQL statement CHECKPOINT SYNC.
*/ */
public void sync() { public void sync() {
int todo; if (readOnly || pageStore == null) {
return;
}
synchronized (this) {
pageStore.sync();
}
} }
public int getMaxMemoryRows() { public int getMaxMemoryRows() {
......
...@@ -6,14 +6,47 @@ ...@@ -6,14 +6,47 @@
*/ */
package org.h2.security; package org.h2.security;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Properties;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.IOUtils;
import org.h2.util.Utils;
/** /**
* A factory to create new block cipher objects. * A factory to create new block cipher objects.
*/ */
public class CipherFactory { public class CipherFactory {
/**
* The default password to use for the .h2.keystore file
*/
public static final String KEYSTORE_PASSWORD = "h2pass";
private static final String KEYSTORE = ".h2.keystore";
private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore";
private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5";
private CipherFactory() { private CipherFactory() {
// utility class // utility class
} }
...@@ -46,4 +79,147 @@ public class CipherFactory { ...@@ -46,4 +79,147 @@ public class CipherFactory {
throw DbException.getInvalidValueException(algorithm, "algorithm"); throw DbException.getInvalidValueException(algorithm, "algorithm");
} }
/**
* Create a secure client socket that is connected to the given address and port.
*
* @param address the address to connect to
* @param port the port
* @return the socket
*/
public static Socket createSocket(InetAddress address, int port) throws IOException {
Socket socket = null;
//## Java 1.4 begin ##
setKeystore();
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket secureSocket = (SSLSocket) f.createSocket();
secureSocket.connect(new InetSocketAddress(address, port),
SysProperties.SOCKET_CONNECT_TIMEOUT);
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
}
socket = secureSocket;
//## Java 1.4 end ##
return socket;
}
/**
* Create a secure server socket. If a bind address is specified, the socket
* is only bound to this address.
*
* @param port the port to listen on
* @param bindAddress the address to bind to, or null to bind to all
* addresses
* @return the server socket
*/
public static ServerSocket createServerSocket(int port, InetAddress bindAddress) throws IOException {
ServerSocket socket = null;
//## Java 1.4 begin ##
setKeystore();
ServerSocketFactory f = SSLServerSocketFactory.getDefault();
SSLServerSocket secureSocket;
if (bindAddress == null) {
secureSocket = (SSLServerSocket) f.createServerSocket(port);
} else {
secureSocket = (SSLServerSocket) f.createServerSocket(port, 0, bindAddress);
}
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
}
socket = secureSocket;
//## Java 1.4 end ##
return socket;
}
//## Java 1.4 begin ##
private static byte[] getKeyStoreBytes(KeyStore store, String password) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
store.store(bout, password.toCharArray());
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
return bout.toByteArray();
}
//## Java 1.4 end ##
/**
* Get the keystore object using the given password.
*
* @param password the keystore password
* @return the keystore
*/
//## Java 1.4 begin ##
public static KeyStore getKeyStore(String password) throws IOException {
try {
// The following source code can be re-generated
// if you have a keystore file.
// This code is (hopefully) more Java version independent
// than using keystores directly. See also:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887561
// (1.4.2 cannot read keystore written with 1.4.1)
// --- generated code start ---
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, password.toCharArray());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
store.load(null, password.toCharArray());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
Utils.convertStringToBytes("30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d02030100010281810099aa4ff4d0a09a5af0bd953cb10c4d08c3d98df565664ac5582e494314d5c3c92dddedd5d316a32a206be4ec084616fe57be15e27cad111aa3c21fa79e32258c6ca8430afc69eddd52d3b751b37da6b6860910b94653192c0db1d02abcfd6ce14c01f238eec7c20bd3bb750940004bacba2880349a9494d10e139ecb2355d101024100ffdc3defd9c05a2d377ef6019fa62b3fbd5b0020a04cc8533bca730e1f6fcf5dfceea1b044fbe17d9eababfbc7d955edad6bc60f9be826ad2c22ba77d19a9f65024100dc28d43fdbbc93852cc3567093157702bc16f156f709fb7db0d9eec028f41fd0edcd17224c866e66be1744141fb724a10fd741c8a96afdd9141b36d67fff6309024077b1cddbde0f69604bdcfe33263fb36ddf24aa3b9922327915b890f8a36648295d0139ecdf68c245652c4489c6257b58744fbdd961834a4cab201801a3b1e52d024100b17142e8991d1b350a0802624759d48ae2b8071a158ff91fabeb6a8f7c328e762143dc726b8529f42b1fab6220d1c676fdc27ba5d44e847c72c52064afd351a902407c6e23fe35bcfcd1a662aa82a2aa725fcece311644d5b6e3894853fd4ce9fe78218c957b1ff03fc9e5ef8ffeb6bd58235f6a215c97d354fdace7e781e4a63e8b"));
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
Certificate[] certs = new Certificate[] { CertificateFactory
.getInstance("X.509")
.generateCertificate(
new ByteArrayInputStream(
Utils.convertStringToBytes("3082018b3081f502044295ce6b300d06092a864886f70d0101040500300d310b3009060355040313024832301e170d3035303532363133323630335a170d3337303933303036353734375a300d310b300906035504031302483230819f300d06092a864886f70d010101050003818d0030818902818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d0203010001300d06092a864886f70d01010405000381810083f4401a279453701bef9a7681a5b8b24f153f7d18c7c892133d97bd5f13736be7505290a445a7d5ceb75522403e5097515cd966ded6351ff60d5193de34cd36e5cb04d380398e66286f99923fd92296645fd4ada45844d194dfd815e6cd57f385c117be982809028bba1116c85740b3d27a55b1a0948bf291ddba44bed337b9"))), };
store.setKeyEntry("h2", privateKey, password.toCharArray(), certs);
// --- generated code end ---
return store;
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
}
private static void setKeystore() throws IOException {
Properties p = System.getProperties();
if (p.getProperty(KEYSTORE_KEY) == null) {
String fileName = IOUtils.getFileInUserHome(KEYSTORE);
byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD);
boolean needWrite = true;
if (IOUtils.exists(fileName) && IOUtils.length(fileName) == data.length) {
// don't need to overwrite the file if it did not change
InputStream fin = IOUtils.openFileInputStream(fileName);
byte[] now = IOUtils.readBytesAndClose(fin, 0);
if (now != null && Utils.compareNotNull(data, now) == 0) {
needWrite = false;
}
}
if (needWrite) {
try {
OutputStream out = IOUtils.openFileOutputStream(fileName, false);
out.write(data);
out.close();
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
}
String absolutePath = IOUtils.getAbsolutePath(fileName);
System.setProperty(KEYSTORE_KEY, absolutePath);
}
if (p.getProperty(KEYSTORE_PASSWORD_KEY) == null) {
System.setProperty(KEYSTORE_PASSWORD_KEY, KEYSTORE_PASSWORD);
}
}
private static String[] addAnonymous(String[] list) {
String[] newList = new String[list.length + 1];
System.arraycopy(list, 0, newList, 1, list.length);
newList[0] = ANONYMOUS_CIPHER_SUITE;
return newList;
}
} }
/*
* Copyright 2004-2010 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.security;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Properties;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.h2.constant.SysProperties;
import org.h2.message.DbException;
import org.h2.util.Utils;
import org.h2.util.IOUtils;
/**
* A factory to create encrypted sockets. To generate new keystore, use the
* SecureKeyStoreBuilder tool.
*/
public class SecureSocketFactory {
/**
* The default password to use for the .h2.keystore file
*/
public static final String KEYSTORE_PASSWORD = "h2pass";
private static final String KEYSTORE = ".h2.keystore";
private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore";
private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5";
private SecureSocketFactory() {
// utility class
}
/**
* Create a secure client socket that is connected to the given address and port.
*
* @param address the address to connect to
* @param port the port
* @return the socket
*/
public static Socket createSocket(InetAddress address, int port) throws IOException {
Socket socket = null;
//## Java 1.4 begin ##
setKeystore();
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket secureSocket = (SSLSocket) f.createSocket();
secureSocket.connect(new InetSocketAddress(address, port),
SysProperties.SOCKET_CONNECT_TIMEOUT);
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
}
socket = secureSocket;
//## Java 1.4 end ##
return socket;
}
/**
* Create a secure server socket. If a bind address is specified, the socket
* is only bound to this address.
*
* @param port the port to listen on
* @param bindAddress the address to bind to, or null to bind to all
* addresses
* @return the server socket
*/
public static ServerSocket createServerSocket(int port, InetAddress bindAddress) throws IOException {
ServerSocket socket = null;
//## Java 1.4 begin ##
setKeystore();
ServerSocketFactory f = SSLServerSocketFactory.getDefault();
SSLServerSocket secureSocket;
if (bindAddress == null) {
secureSocket = (SSLServerSocket) f.createServerSocket(port);
} else {
secureSocket = (SSLServerSocket) f.createServerSocket(port, 0, bindAddress);
}
if (SysProperties.ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
secureSocket.setEnabledCipherSuites(list);
}
socket = secureSocket;
//## Java 1.4 end ##
return socket;
}
//## Java 1.4 begin ##
private static byte[] getBytes(String hex) {
return Utils.convertStringToBytes(hex);
}
private static byte[] getKeyStoreBytes(KeyStore store, String password) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
store.store(bout, password.toCharArray());
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
return bout.toByteArray();
}
//## Java 1.4 end ##
/**
* Get the keystore object using the given password.
*
* @param password the keystore password
* @return the keystore
*/
//## Java 1.4 begin ##
public static KeyStore getKeyStore(String password) throws IOException {
try {
// The following source code can be re-generated
// if you have a keystore file.
// This code is (hopefully) more Java version independent
// than using keystores directly. See also:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887561
// (1.4.2 cannot read keystore written with 1.4.1)
// --- generated code start ---
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, password.toCharArray());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
store.load(null, password.toCharArray());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
getBytes("30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d02030100010281810099aa4ff4d0a09a5af0bd953cb10c4d08c3d98df565664ac5582e494314d5c3c92dddedd5d316a32a206be4ec084616fe57be15e27cad111aa3c21fa79e32258c6ca8430afc69eddd52d3b751b37da6b6860910b94653192c0db1d02abcfd6ce14c01f238eec7c20bd3bb750940004bacba2880349a9494d10e139ecb2355d101024100ffdc3defd9c05a2d377ef6019fa62b3fbd5b0020a04cc8533bca730e1f6fcf5dfceea1b044fbe17d9eababfbc7d955edad6bc60f9be826ad2c22ba77d19a9f65024100dc28d43fdbbc93852cc3567093157702bc16f156f709fb7db0d9eec028f41fd0edcd17224c866e66be1744141fb724a10fd741c8a96afdd9141b36d67fff6309024077b1cddbde0f69604bdcfe33263fb36ddf24aa3b9922327915b890f8a36648295d0139ecdf68c245652c4489c6257b58744fbdd961834a4cab201801a3b1e52d024100b17142e8991d1b350a0802624759d48ae2b8071a158ff91fabeb6a8f7c328e762143dc726b8529f42b1fab6220d1c676fdc27ba5d44e847c72c52064afd351a902407c6e23fe35bcfcd1a662aa82a2aa725fcece311644d5b6e3894853fd4ce9fe78218c957b1ff03fc9e5ef8ffeb6bd58235f6a215c97d354fdace7e781e4a63e8b"));
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
Certificate[] certs = new Certificate[] { CertificateFactory
.getInstance("X.509")
.generateCertificate(
new ByteArrayInputStream(
getBytes("3082018b3081f502044295ce6b300d06092a864886f70d0101040500300d310b3009060355040313024832301e170d3035303532363133323630335a170d3337303933303036353734375a300d310b300906035504031302483230819f300d06092a864886f70d010101050003818d0030818902818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d0203010001300d06092a864886f70d01010405000381810083f4401a279453701bef9a7681a5b8b24f153f7d18c7c892133d97bd5f13736be7505290a445a7d5ceb75522403e5097515cd966ded6351ff60d5193de34cd36e5cb04d380398e66286f99923fd92296645fd4ada45844d194dfd815e6cd57f385c117be982809028bba1116c85740b3d27a55b1a0948bf291ddba44bed337b9"))), };
store.setKeyEntry("h2", privateKey, password.toCharArray(), certs);
// --- generated code end ---
return store;
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
}
private static void setKeystore() throws IOException {
Properties p = System.getProperties();
if (p.getProperty(KEYSTORE_KEY) == null) {
String fileName = IOUtils.getFileInUserHome(KEYSTORE);
byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD);
boolean needWrite = true;
if (IOUtils.exists(fileName) && IOUtils.length(fileName) == data.length) {
// don't need to overwrite the file if it did not change
InputStream fin = IOUtils.openFileInputStream(fileName);
byte[] now = IOUtils.readBytesAndClose(fin, 0);
if (now != null && Utils.compareNotNull(data, now) == 0) {
needWrite = false;
}
}
if (needWrite) {
try {
OutputStream out = IOUtils.openFileOutputStream(fileName, false);
out.write(data);
out.close();
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
}
String absolutePath = IOUtils.getAbsolutePath(fileName);
System.setProperty(KEYSTORE_KEY, absolutePath);
}
if (p.getProperty(KEYSTORE_PASSWORD_KEY) == null) {
System.setProperty(KEYSTORE_PASSWORD_KEY, KEYSTORE_PASSWORD);
}
}
private static String[] addAnonymous(String[] list) {
String[] newList = new String[list.length + 1];
System.arraycopy(list, 0, newList, 1, list.length);
newList[0] = ANONYMOUS_CIPHER_SUITE;
return newList;
}
//## Java 1.4 end ##
}
...@@ -448,8 +448,12 @@ public class FileStore { ...@@ -448,8 +448,12 @@ public class FileStore {
* Call fsync. Depending on the operating system and hardware, this may or * Call fsync. Depending on the operating system and hardware, this may or
* may not in fact write the changes. * may not in fact write the changes.
*/ */
public void sync() throws IOException { public void sync() {
file.sync(); try {
file.sync();
} catch (IOException e) {
throw DbException.convertIOException(e, name);
}
} }
/** /**
......
...@@ -704,6 +704,18 @@ public class PageStore implements CacheWriter { ...@@ -704,6 +704,18 @@ public class PageStore implements CacheWriter {
} }
} }
/**
* Flush the transaction log and sync the file.
*/
public void sync() {
if (file != null) {
synchronized (database) {
log.flush();
file.sync();
}
}
}
public Trace getTrace() { public Trace getTrace() {
return trace; return trace;
} }
......
...@@ -13,7 +13,6 @@ import java.util.ArrayList; ...@@ -13,7 +13,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
/** /**
...@@ -146,49 +145,6 @@ public class MultiDimension implements Comparator<long[]> { ...@@ -146,49 +145,6 @@ public class MultiDimension implements Comparator<long[]> {
return prep.executeQuery(); return prep.executeQuery();
} }
/**
* Generates an optimized multi-dimensional range query.
* This query is database independent, however the performance is
* not as good as when using generatePreparedQuery
*
* @param table the table name
* @param columns the list of columns
* @param min the lower values
* @param max the upper values
* @param scalarColumn the column name of the computed scalar column
* @return the query
*/
public String generateQuery(String table, String scalarColumn, String[] columns, int[] min, int[] max) {
long[][] ranges = getMortonRanges(min, max);
StatementBuilder buff = new StatementBuilder("SELECT * FROM (");
for (long[] range : ranges) {
long minScalar = range[0];
long maxScalar = range[1];
buff.appendExceptFirst(" UNION ALL ");
buff.append("SELECT * FROM ").
append(table).
append(" WHERE ").
append(scalarColumn).
append(" BETWEEN ").
append(minScalar).
append(" AND ").
append(maxScalar);
}
buff.append(") WHERE ");
int i = 0;
buff.resetCount();
for (String col : columns) {
buff.appendExceptFirst(" AND ");
buff.append(col).
append(" BETWEEN ").
append(min[i]).
append(" AND ").
append(max[i]);
i++;
}
return buff.toString();
}
/** /**
* Gets a list of ranges to be searched for a multi-dimensional range query * Gets a list of ranges to be searched for a multi-dimensional range query
* where min &lt;= value &lt;= max. In most cases, the ranges will be larger * where min &lt;= value &lt;= max. In most cases, the ranges will be larger
......
...@@ -17,7 +17,7 @@ import java.net.UnknownHostException; ...@@ -17,7 +17,7 @@ import java.net.UnknownHostException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.security.SecureSocketFactory; import org.h2.security.CipherFactory;
/** /**
* This utility class contains socket helper functions. * This utility class contains socket helper functions.
...@@ -103,7 +103,7 @@ public class NetUtils { ...@@ -103,7 +103,7 @@ public class NetUtils {
for (int i = 0;; i++) { for (int i = 0;; i++) {
try { try {
if (ssl) { if (ssl) {
return SecureSocketFactory.createSocket(address, port); return CipherFactory.createSocket(address, port);
} }
Socket socket = new Socket(); Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port), socket.connect(new InetSocketAddress(address, port),
...@@ -165,7 +165,7 @@ public class NetUtils { ...@@ -165,7 +165,7 @@ public class NetUtils {
try { try {
InetAddress bindAddress = getBindAddress(); InetAddress bindAddress = getBindAddress();
if (ssl) { if (ssl) {
return SecureSocketFactory.createServerSocket(port, bindAddress); return CipherFactory.createServerSocket(port, bindAddress);
} }
if (bindAddress == null) { if (bindAddress == null) {
return new ServerSocket(port); return new ServerSocket(port);
......
...@@ -263,6 +263,11 @@ java org.h2.test.TestAll timer ...@@ -263,6 +263,11 @@ java org.h2.test.TestAll timer
*/ */
boolean stopOnError; boolean stopOnError;
/**
* The cache type.
*/
String cacheType;
private Server server; private Server server;
/** /**
...@@ -286,10 +291,10 @@ java org.h2.test.TestAll timer ...@@ -286,10 +291,10 @@ java org.h2.test.TestAll timer
System.setProperty("h2.check2", "true"); System.setProperty("h2.check2", "true");
/* /*
implement FileStore.sync, Database.sync() (CHECKPOINT SYNC) rename Page* classes
try to replace 'catch Exception' with 'catch DbException' move classes to the right packages
try again with -verbose:classes
test Row.getMemorySize test Row.getMemorySize
remove CipherFactory
document in performance section: document in performance section:
PreparedStatement prep = conn.prepareStatement( PreparedStatement prep = conn.prepareStatement(
...@@ -416,6 +421,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -416,6 +421,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
deleteIndex = true; deleteIndex = true;
traceLevelFile = 3; traceLevelFile = 3;
throttle = 1; throttle = 1;
cacheType = "SOFT_LRU";
cipher = "XTEA"; cipher = "XTEA";
test(); test();
...@@ -424,6 +430,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -424,6 +430,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
deleteIndex = false; deleteIndex = false;
traceLevelFile = 1; traceLevelFile = 1;
throttle = 0; throttle = 0;
cacheType = null;
cipher = null; cipher = null;
test(); test();
...@@ -672,6 +679,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -672,6 +679,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
appendIf(buff, codeCoverage, "codeCoverage"); appendIf(buff, codeCoverage, "codeCoverage");
appendIf(buff, mvcc, "mvcc"); appendIf(buff, mvcc, "mvcc");
appendIf(buff, cipher != null, cipher); appendIf(buff, cipher != null, cipher);
appendIf(buff, cacheType != null, cacheType);
appendIf(buff, jdk14, "jdk14"); appendIf(buff, jdk14, "jdk14");
appendIf(buff, smallLog, "smallLog"); appendIf(buff, smallLog, "smallLog");
appendIf(buff, ssl, "ssl"); appendIf(buff, ssl, "ssl");
......
...@@ -264,6 +264,9 @@ public abstract class TestBase { ...@@ -264,6 +264,9 @@ public abstract class TestBase {
if (config.mvcc && url.indexOf("MVCC=") < 0) { if (config.mvcc && url.indexOf("MVCC=") < 0) {
url += ";MVCC=TRUE"; url += ";MVCC=TRUE";
} }
if (config.cacheType != null && admin && url.indexOf("CACHE_TYPE=") < 0) {
url += ";CACHE_TYPE=" + config.cacheType;
}
if (config.diskResult && admin) { if (config.diskResult && admin) {
url += ";MAX_MEMORY_ROWS=100;CACHE_SIZE=0"; url += ";MAX_MEMORY_ROWS=100;CACHE_SIZE=0";
} }
......
...@@ -101,7 +101,12 @@ class Database { ...@@ -101,7 +101,12 @@ class Database {
Thread.sleep(100); Thread.sleep(100);
} else if (url.startsWith("jdbc:hsqldb:hsql:")) { } else if (url.startsWith("jdbc:hsqldb:hsql:")) {
if (!serverHSQLDB) { if (!serverHSQLDB) {
Class< ? > c = Class.forName("org.hsqldb.Server"); Class< ? > c;
try {
c = Class.forName("org.hsqldb.server.Server");
} catch (Exception e) {
c = Class.forName("org.hsqldb.Server");
}
Method m = c.getMethod("main", String[].class); Method m = c.getMethod("main", String[].class);
m.invoke(null, new Object[] { new String[] { "-database.0", m.invoke(null, new Object[] { new String[] { "-database.0",
"data/mydb;hsqldb.default_table_type=cached", "-dbname.0", "xdb" } }); "data/mydb;hsqldb.default_table_type=cached", "-dbname.0", "xdb" } });
......
...@@ -11,10 +11,12 @@ import java.sql.PreparedStatement; ...@@ -11,10 +11,12 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.HashMap;
import java.util.Random; import java.util.Random;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.New;
/** /**
* Index tests. * Index tests.
...@@ -36,6 +38,7 @@ public class TestIndex extends TestBase { ...@@ -36,6 +38,7 @@ public class TestIndex extends TestBase {
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("index"); deleteDb("index");
testNonUniqueHashIndex();
testRenamePrimaryKey(); testRenamePrimaryKey();
testRandomized(); testRandomized();
testDescIndex(); testDescIndex();
...@@ -84,6 +87,41 @@ public class TestIndex extends TestBase { ...@@ -84,6 +87,41 @@ public class TestIndex extends TestBase {
deleteDb("index"); deleteDb("index");
} }
private void testNonUniqueHashIndex() throws SQLException {
reconnect();
stat.execute("create memory table test(id bigint, data bigint)");
stat.execute("create hash index on test(id)");
Random rand = new Random(1);
PreparedStatement prepInsert = conn.prepareStatement("insert into test values(?, ?)");
PreparedStatement prepDelete = conn.prepareStatement("delete from test where id=?");
PreparedStatement prepSelect = conn.prepareStatement("select count(*) from test where id=?");
HashMap<Long, Integer> map = New.hashMap();
for (int i = 0; i < 1000; i++) {
long key = rand.nextInt(10) * 1000000000L;
Integer r = map.get(key);
int result = r == null ? 0 : (int) r;
if (rand.nextBoolean()) {
prepSelect.setLong(1, key);
ResultSet rs = prepSelect.executeQuery();
rs.next();
assertEquals(result, rs.getInt(1));
} else {
if (rand.nextBoolean()) {
prepInsert.setLong(1, key);
prepInsert.setInt(2, rand.nextInt());
prepInsert.execute();
map.put(key, result + 1);
} else {
prepDelete.setLong(1, key);
prepDelete.execute();
map.put(key, 0);
}
}
}
stat.execute("drop table test");
conn.close();
}
private void testRenamePrimaryKey() throws SQLException { private void testRenamePrimaryKey() throws SQLException {
if (config.memory) { if (config.memory) {
return; return;
......
...@@ -113,33 +113,6 @@ public class TestMultiDimension extends TestBase { ...@@ -113,33 +113,6 @@ public class TestMultiDimension extends TestBase {
} }
assertFalse(rs2.next()); assertFalse(rs2.next());
} }
trace("multi: " + timeMulti + " regular: " + timeRegular);
for (int i = 0; i < 50; i++) {
int size = rand.nextInt(max / 10);
int minX = rand.nextInt(max - size);
int minY = rand.nextInt(max - size);
int minZ = rand.nextInt(max - size);
int maxX = minX + size, maxY = minY + size, maxZ = minZ + size;
long time1 = System.currentTimeMillis();
String query1 = MultiDimension.getInstance().generateQuery("TEST", "XYZ", new String[] { "X", "Y", "Z" },
new int[] { minX, minY, minZ }, new int[] { minX + size, minY + size, minZ + size });
ResultSet rs1 = conn.createStatement().executeQuery(query1 + " ORDER BY X, Y, Z");
time1 = System.currentTimeMillis() - time1;
long time2 = System.currentTimeMillis();
String query2 = "SELECT * FROM TEST WHERE " + "X BETWEEN " + minX + " AND " + maxX + " AND " + "Y BETWEEN "
+ minY + " AND " + maxY + " AND " + "Z BETWEEN " + minZ + " AND " + maxZ;
PreparedStatement prep2 = conn.prepareStatement(query2 + " ORDER BY X, Y, Z");
ResultSet rs2 = prep2.executeQuery();
time2 = System.currentTimeMillis() - time2;
while (rs1.next()) {
assertTrue(rs2.next());
assertEquals(rs1.getInt(1), rs2.getInt(1));
assertEquals(rs1.getInt(2), rs2.getInt(2));
}
assertFalse(rs2.next());
// it just has to work, no need to compare the performance
// trace("t1="+time1+" t2="+time2+" size="+size);
}
conn.close(); conn.close();
deleteDb("multiDimension"); deleteDb("multiDimension");
} }
......
...@@ -61,6 +61,14 @@ public class TestPgServer extends TestBase { ...@@ -61,6 +61,14 @@ public class TestPgServer extends TestBase {
conn.close(); conn.close();
conn = DriverManager.getConnection("jdbc:postgresql://localhost:5535/test", "sa", "sa"); conn = DriverManager.getConnection("jdbc:postgresql://localhost:5535/test", "sa", "sa");
stat = conn.createStatement(); stat = conn.createStatement();
ResultSet rs;
stat.execute("prepare test(int, int) as select ?1*?2");
rs = stat.executeQuery("execute test(3, 2)");
rs.next();
assertEquals(6, rs.getInt(1));
stat.execute("deallocate test");
stat.execute("create table test(id int primary key, name varchar)"); stat.execute("create table test(id int primary key, name varchar)");
PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)"); PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)");
ParameterMetaData meta = prep.getParameterMetaData(); ParameterMetaData meta = prep.getParameterMetaData();
...@@ -68,7 +76,7 @@ public class TestPgServer extends TestBase { ...@@ -68,7 +76,7 @@ public class TestPgServer extends TestBase {
prep.setInt(1, 1); prep.setInt(1, 1);
prep.setString(2, "Hello"); prep.setString(2, "Hello");
prep.execute(); prep.execute();
ResultSet rs = stat.executeQuery("select * from test"); rs = stat.executeQuery("select * from test");
rs.next(); rs.next();
ResultSetMetaData rsMeta = rs.getMetaData(); ResultSetMetaData rsMeta = rs.getMetaData();
......
...@@ -15,7 +15,7 @@ import java.security.cert.Certificate; ...@@ -15,7 +15,7 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.util.Enumeration; import java.util.Enumeration;
import org.h2.security.SecureSocketFactory; import org.h2.security.CipherFactory;
import org.h2.util.Utils; import org.h2.util.Utils;
/** /**
...@@ -41,8 +41,8 @@ public class SecureKeyStoreBuilder { ...@@ -41,8 +41,8 @@ public class SecureKeyStoreBuilder {
* @param args the command line parameters * @param args the command line parameters
*/ */
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
String password = SecureSocketFactory.KEYSTORE_PASSWORD; String password = CipherFactory.KEYSTORE_PASSWORD;
KeyStore store = SecureSocketFactory.getKeyStore(password); KeyStore store = CipherFactory.getKeyStore(password);
printKeystore(store, password); printKeystore(store, password);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论