提交 68882ef5 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 2bc107ec
#Tue Mar 18 08:37:19 CET 2008
#Thu Mar 20 17:07:30 CET 2008
benchmark.drivers.dir=C\:/data/java
javac=javac
jdk=1.4
......
......@@ -52,29 +52,29 @@
</target>
<target name="codeswitchPrepare" depends="clean">
<javac executable="${javac}" srcdir="src/tools" destdir="bin" debug="true" includes="org/h2/tools/code/CodeSwitch.java"/>
<javac executable="${javac}" srcdir="src/tools" destdir="bin" debug="true" includes="org/h2/build/code/CodeSwitch.java"/>
</target>
<target name="codeswitchAndroid" depends="codeswitchPrepare">
<java classname="org.h2.tools.code.CodeSwitch" classpath="bin">
<java classname="org.h2.build.code.CodeSwitch" classpath="bin">
<arg line="+JDK13 -JDK14 -JDK16 -AWT src/main/org/h2 -set ant-build.properties jdk 1.3"/>
</java>
</target>
<target name="codeswitchJdk13" depends="codeswitchPrepare">
<java classname="org.h2.tools.code.CodeSwitch" classpath="bin">
<java classname="org.h2.build.code.CodeSwitch" classpath="bin">
<arg line="+JDK13 -JDK14 -JDK16 +AWT src/main/org/h2 -set ant-build.properties jdk 1.3"/>
</java>
</target>
<target name="codeswitchJdk14" depends="codeswitchPrepare">
<java classname="org.h2.tools.code.CodeSwitch" classpath="bin">
<java classname="org.h2.build.code.CodeSwitch" classpath="bin">
<arg line="-JDK13 +JDK14 -JDK16 +AWT src/main/org/h2 -set ant-build.properties jdk 1.4"/>
</java>
</target>
<target name="codeswitchJdk16" depends="codeswitchPrepare">
<java classname="org.h2.tools.code.CodeSwitch" classpath="bin">
<java classname="org.h2.build.code.CodeSwitch" classpath="bin">
<arg line="-JDK13 +JDK14 +JDK16 +AWT src/main/org/h2 -set ant-build.properties jdk 1.6"/>
</java>
</target>
......@@ -163,16 +163,16 @@
<copy todir="docs">
<fileset dir="src/docsrc" includes="index.html"/>
</copy>
<java classname="org.h2.tools.code.CheckJavadoc" classpath="bin"/>
<java classname="org.h2.tools.code.CheckTextFiles" classpath="bin"/>
<java classname="org.h2.tools.doc.GenerateDoc" classpath="bin"/>
<java classname="org.h2.tools.i18n.PrepareTranslation" classpath="bin"/>
<java classname="org.h2.tools.indexer.Indexer" classpath="bin"/>
<java classname="org.h2.tools.doc.MergeDocs" classpath="bin"/>
<java classname="org.h2.tools.doc.WebSite" classpath="bin"/>
<java classname="org.h2.tools.doc.LinkChecker" classpath="bin"/>
<java classname="org.h2.tools.doc.XMLChecker" classpath="bin"/>
<java classname="org.h2.tools.doc.SpellChecker" classpath="bin"/>
<java classname="org.h2.build.code.CheckJavadoc" classpath="bin"/>
<java classname="org.h2.build.code.CheckTextFiles" classpath="bin"/>
<java classname="org.h2.build.doc.GenerateDoc" classpath="bin"/>
<java classname="org.h2.build.i18n.PrepareTranslation" classpath="bin"/>
<java classname="org.h2.build.indexer.Indexer" classpath="bin"/>
<java classname="org.h2.build.doc.MergeDocs" classpath="bin"/>
<java classname="org.h2.build.doc.WebSite" classpath="bin"/>
<java classname="org.h2.build.doc.LinkChecker" classpath="bin"/>
<java classname="org.h2.build.doc.XMLChecker" classpath="bin"/>
<java classname="org.h2.build.doc.SpellChecker" classpath="bin"/>
</target>
<target name="init">
......@@ -200,12 +200,10 @@
</manifest>
<jar jarfile="bin/h2.jar" basedir="bin" manifest="bin/META-INF/MANIFEST.MF">
<include name="**/*.*"/>
<exclude name="org/h2/tools/code/**/*.*"/>
<exclude name="org/h2/tools/doc/**/*.*"/>
<exclude name="org/h2/tools/doclet/**/*.*"/>
<exclude name="org/h2/tools/indexer/**/*.*"/>
<exclude name="org/h2/test/**/*.*"/>
<exclude name="org/h2/build/**/*.*"/>
<exclude name="org/h2/dev/**/*.*"/>
<exclude name="org/h2/samples/**/*.*"/>
<exclude name="org/h2/test/**/*.*"/>
<exclude name="**/*.bat"/>
<exclude name="**/*.txt"/>
</jar>
......@@ -239,12 +237,12 @@
<target name="javadoc">
<javac executable="${javac}" srcdir="src/main" destdir="bin" debug="true" includes="org/h2/util/StringUtils.java"/>
<javac executable="${javac}" srcdir="src/test" destdir="bin" debug="true" includes="org/h2/test/bnf/*.java"/>
<javac executable="${javac}" srcdir="src/tools" destdir="bin" debug="true" includes="org/h2/tools/doclet/*.java"/>
<javac executable="${javac}" srcdir="src/tools" destdir="bin" debug="true" includes="org/h2/build/doclet/*.java"/>
<mkdir dir="docs/javadoc"/>
<javadoc
sourcepath="src/main"
packagenames="org.h2.jdbc.*,org.h2.jdbcx.*,org.h2.tools.*,org.h2.api.*,org.h2.constant.*"
doclet="org.h2.tools.doclet.Doclet"
doclet="org.h2.build.doclet.Doclet"
docletpath="bin"
/>
<copy todir="docs/javadoc">
......@@ -258,7 +256,7 @@
sourcepath="src/main;src/test;src/tools"
classpath="${path.lucene.jar};${path.servlet.jar};${java.class.path}"
packagenames="org.h2.*"
doclet="org.h2.tools.doclet.Doclet"
doclet="org.h2.build.doclet.Doclet"
docletpath="bin"
additionalparam="-J-Dh2.interfacesOnly=false -J-Dh2.destDir=docs/javadocImpl"
/>
......@@ -266,7 +264,7 @@
sourcepath="src/main;src/test;src/tools"
noindex="true"
packagenames="org.h2.*"
excludepackagenames="org.h2.tools.doclet"
excludepackagenames="org.h2.build.*,org.h2.dev.*"
classpath="${path.lucene.jar};${path.servlet.jar};${java.class.path}"
destDir="docs/javadocImpl"
/>
......
......@@ -32,6 +32,8 @@ Advanced Topics
Run as Windows Service</a><br />
<a href="#odbc_driver">
ODBC Driver</a><br />
<a href="#microsoft_dot_net">
Using H2 in Microsoft .NET</a><br />
<a href="#acid">
ACID</a><br />
<a href="#durability_problems">
......@@ -474,6 +476,29 @@ Also, it is currently not possible to use encrypted SSL connections.
Therefore the ODBC driver should not be used where security is important.
</p>
<br /><a name="microsoft_dot_net"></a>
<h2>Using H2 in Microsoft .NET</h2>
<p>
The database can be used from Microsoft .NET even without using Java, by using IKVM.NET:
</p>
<ul><li>Install the .NET Framework from <a href="http://www.microsoft.com">Microsoft</a>.
Mono has not yet been tested.
</li><li>Install <a href="http://www.ikvm.net">IKVM.NET</a>.
</li><li>Copy the h2.jar file to ikvm/bin
</li><li>Run the H2 Console using:
<code>ikvm -jar h2.jar</code>
</li><li>Convert the H2 Console to an .exe file using:
<code>ikvmc -target:winexe h2.jar</code>.
You may ignore the warnings.
</li><li>Create a .dll file using (change the version accordingly):
<code>ikvmc.exe -target:library -version:1.0.68.0 h2.jar</code>
</li></ul>
<p>
If you want your C# application use H2, you need to add the h2.dll and the
IKVM.OpenJDK.ClassLibrary.dll to your C# solution. See also the short
<a href="http://groups.google.com/group/h2-database/browse_thread/thread/400bc5a9bc9de3fd">C# source code example</a>.
</p>
<br /><a name="acid"></a>
<h2>ACID</h2>
<p>
......
......@@ -230,6 +230,11 @@ Orion</a><br />
J2EE Application Server.
</p>
<p><a href="http://www.phase-6.de">
Phase-6</a><br />
A computer based learning software.
</p>
<p><a href="http://www.polepos.org">
PolePosition</a><br />
Open source database benchmark.
......
......@@ -18,7 +18,7 @@ Welcome to H2, the free SQL database engine.
<br />
<p>
<a href="quickstartText.html" style="font-size: 16px; font-weight: bold">Quickstart</a>
<a href="quickstart.html" style="font-size: 16px; font-weight: bold">Quickstart</a>
<br />
Click here to get a fast overview.
</p>
......
......@@ -52,7 +52,7 @@ Initial Developer: H2 Group
<div class="menu">
<b><a href="main.html" target="main">Home</a></b><br />
<a href="quickstartText.html" target="main">Quickstart</a><br />
<a href="quickstart.html" target="main">Quickstart</a><br />
<a href="installation.html" target="main">Installation</a><br />
<a href="tutorial.html" target="main">Tutorial</a><br />
<a href="features.html" target="main">Features</a><br />
......
......@@ -28,6 +28,8 @@ Tutorial
CSV (Comma Separated Values) Support</a><br />
<a href="#upgrade_backup_restore">
Upgrade, Backup, and Restore</a><br />
<a href="#command_line_tools">
Command Line Tools</a><br />
<a href="#open_office">
Using OpenOffice Base</a><br />
<a href="#web_start">
......@@ -492,6 +494,36 @@ The Backup tool (org.h2.tools.Backup) can not be used to create a online backup;
the database must not be in use while running this program.
</p>
<br /><a name="command_line_tools"></a>
<h2>Command Line Tools</h2>
<p>
This database comes with a number of command line tools. To get more information about a tool,
start it with the parameter '-?', for example:
</p>
<pre>
java -cp h2.jar org.h2.tools.Backup -?
</pre>
<p>
The command line tools are:
</p>
<ul><li><b>Backup</b> creates a backup of a database.
</li><li><b>ChangePassword</b> allows to change the file password of a database.
</li><li><b>Console</b> starts the browser based H2 Console.
</li><li><b>ConvertTraceFile</b> converts a .trace.db file to a Java application and SQL script.
</li><li><b>CreateCluster</b> creates a cluster from a standalone database.
</li><li><b>DeleteDbFiles</b> deletes all files belonging to a database.
</li><li><b>Script</b> allows to convert a database to a SQL script for backup or migration.
</li><li><b>Recover</b> helps recovering a corrupted database.
</li><li><b>Restore</b> restores a backup of a database.
</li><li><b>RunScript</b> runs a SQL script against a database.
</li><li><b>Server</b> is used in the server mode to start a H2 server.
</li><li><b>Shell</b> is a command line database tool.
</li></ul>
<p>
The tools can also be called from an application by calling the main or another public methods.
For details, see the Javadoc documentation.
</p>
<br /><a name="open_office"></a>
<h2>Using OpenOffice Base</h2>
<p>
......@@ -557,11 +589,28 @@ Example permission tags:
For many databases, opening a connection is slow, and it is a good idea to use a connection pool
to re-use connections. For H2 however opening a connection usually is fast if the database is already
open. Using a connection pool manager for H2 actually slows down the process a bit, except if
file encryption is used (in this case opening a connection is about half as fast are using
a connection pool). A simple connection pool is:
<a href="http://www.source-code.biz/snippets/java/8.htm">Mini Connection Pool Manager</a>.
There are other, more complex connection pools available, for example
<a href="http://jakarta.apache.org/commons/dbcp/">DBCP</a>.
file encryption is used (in this case opening a connection is about half as fast as using
a connection pool). A simple connection pool manager is included in H2. It is based on the
<a href="http://www.source-code.biz/snippets/java/8.htm">Mini Connection Pool Manager</a>
from Christian d'Heureuse. There are other, more complex connection pools available, for example
<a href="http://jakarta.apache.org/commons/dbcp/">DBCP</a>. The build-in
connection pool manager is used as follows:
<pre>
// init
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:~/test");
ds.setUser("sa");
ds.setPassword("sa");
JdbcConnectionPoolManager man = new JdbcConnectionPoolManager(ds);
// use
Connection conn = man.getConnection();
...
conn.close();
// dispose
man.dispose();
</pre>
</p>
<br /><a name="fulltext"></a>
......
......@@ -37,6 +37,7 @@ org.h2.jdbc<br />
<a href="org/h2/jdbc/JdbcSQLException.html" target="javadoc">SQLException</a><br />
<a href="org/h2/jdbc/JdbcStatement.html" target="javadoc">Statement</a><br />
org.h2.jdbcx<br />
<a href="org/h2/jdbcx/JdbcConnectionPoolManager.html" target="javadoc">ConnectionPoolManager</a><br />
<a href="org/h2/jdbcx/JdbcDataSource.html" target="javadoc">DataSource</a><br />
<a href="org/h2/jdbcx/JdbcDataSourceFactory.html" target="javadoc">DataSourceFactory</a><br />
<a href="org/h2/jdbcx/JdbcXAConnection.html" target="javadoc">XAConnection</a><br />
......@@ -59,6 +60,7 @@ org.h2.tools<br />
<a href="org/h2/tools/Restore.html" target="javadoc">Restore</a><br />
<a href="org/h2/tools/RunScript.html" target="javadoc">RunScript</a><br />
<a href="org/h2/tools/Server.html" target="javadoc">Server</a><br />
<a href="org/h2/tools/Shell.html" target="javadoc">Shell</a><br />
<a href="org/h2/tools/SimpleResultSet.html" target="javadoc">SimpleResultSet</a><br />
<a href="org/h2/tools/SimpleRowSource.html" target="javadoc">SimpleRowSource</a><br />
<br />
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: Christian d'Heureuse, www.source-code.biz
*
* This class is dual-licensed LGPL and under the H2 License.
*
* This module is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version. See http://www.gnu.org/licenses/lgpl.html.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
package org.h2.jdbcx;
import java.util.Stack;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.PooledConnection;
/**
* A simple standalone JDBC connection pool manager.
* It is based on the
* <a href="http://www.source-code.biz/snippets/java/8.htm">
* MiniConnectionPoolManager written by Christian d'Heureuse (JDK 1.5)
* </a>.
*
* @author Christian d'Heureuse (<a href="http://www.source-code.biz">www.source-code.biz</a>)
* @author Thomas Mueller (ported to JDK 1.4)
*/
public class JdbcConnectionPoolManager {
private ConnectionPoolDataSource dataSource;
private int maxConnections;
private int timeout;
private PrintWriter logWriter;
private Stack recycledConnections;
private int activeConnections;
private PoolConnectionEventListener poolConnectionEventListener;
private boolean isDisposed;
/**
* This inThrown in {@link #getConnection()} when no free connection becomes
* available within <code>timeout</code> seconds.
*/
public static class TimeoutException extends RuntimeException {
private static final long serialVersionUID = 1;
public TimeoutException() {
super("Timeout while waiting for a free database connection.");
}
}
/**
* Constructs a JdbcConnectionPoolManager object with a timeout of 60
* seconds.
*
* @param dataSource the data source for the connections.
* @param maxConnections the maximum number of connections.
*/
public JdbcConnectionPoolManager(ConnectionPoolDataSource dataSource, int maxConnections) {
this(dataSource, maxConnections, 60);
}
/**
* Constructs a JdbcConnectionPoolManager object.
*
* @param dataSource the data source for the connections.
* @param maxConnections the maximum number of connections.
* @param timeout the maximum time in seconds to wait for a free connection.
*/
public JdbcConnectionPoolManager(ConnectionPoolDataSource dataSource, int maxConnections, int timeout) {
this.dataSource = dataSource;
this.maxConnections = maxConnections;
this.timeout = timeout;
try {
logWriter = dataSource.getLogWriter();
} catch (SQLException e) {
}
if (maxConnections < 1) {
throw new IllegalArgumentException("Invalid maxConnections value.");
}
recycledConnections = new Stack();
poolConnectionEventListener = new PoolConnectionEventListener();
}
/**
* Closes all unused pooled connections.
*/
public synchronized void dispose() throws SQLException {
if (isDisposed) {
return;
}
isDisposed = true;
SQLException e = null;
while (!recycledConnections.isEmpty()) {
PooledConnection pc = (PooledConnection) recycledConnections.pop();
try {
pc.close();
} catch (SQLException e2) {
if (e == null) {
e = e2;
}
}
}
if (e != null) {
throw e;
}
}
/**
* Retrieves a connection from the connection pool. If
* <code>maxConnections</code> connections are already in use, the method
* waits until a connection becomes available or <code>timeout</code>
* seconds elapsed. When the application is finished using the connection,
* it must close it in order to return it to the pool.
*
* @return a new Connection object.
* @throws TimeoutException when no connection becomes available within
* <code>timeout</code> seconds.
*/
public Connection getConnection() throws SQLException {
for (int i = 0;; i++) {
synchronized (this) {
if (activeConnections < maxConnections) {
return getConnectionNow();
}
if (i >= timeout) {
throw new TimeoutException();
}
try {
wait(1000);
} catch (InterruptedException e) {
// ignore
}
}
}
}
private Connection getConnectionNow() throws SQLException {
if (isDisposed) {
throw new IllegalStateException("Connection pool has been disposed.");
}
PooledConnection pc;
if (!recycledConnections.empty()) {
pc = (PooledConnection) recycledConnections.pop();
} else {
pc = dataSource.getPooledConnection();
}
Connection conn = pc.getConnection();
activeConnections++;
pc.addConnectionEventListener(poolConnectionEventListener);
assertInnerState();
return conn;
}
private synchronized void recycleConnection(PooledConnection pc) {
if (isDisposed) {
disposeConnection(pc);
return;
}
if (activeConnections <= 0) {
throw new AssertionError();
}
activeConnections--;
notifyAll();
recycledConnections.push(pc);
assertInnerState();
}
private synchronized void disposeConnection(PooledConnection pc) {
if (activeConnections <= 0) {
throw new AssertionError();
}
activeConnections--;
notifyAll();
try {
pc.close();
} catch (SQLException e) {
log("Error while closing database connection: " + e.toString());
}
assertInnerState();
}
private void log(String msg) {
String s = "JdbcConnectionPoolManager: " + msg;
try {
if (logWriter == null) {
System.err.println(s);
} else {
logWriter.println(s);
}
} catch (Exception e) {
}
}
private void assertInnerState() {
if (activeConnections < 0) {
throw new AssertionError();
}
if (activeConnections + recycledConnections.size() > maxConnections) {
throw new AssertionError();
}
}
private class PoolConnectionEventListener implements ConnectionEventListener {
public void connectionClosed(ConnectionEvent event) {
PooledConnection pc = (PooledConnection) event.getSource();
pc.removeConnectionEventListener(this);
recycleConnection(pc);
}
public void connectionErrorOccurred(ConnectionEvent event) {
PooledConnection pc = (PooledConnection) event.getSource();
pc.removeConnectionEventListener(this);
disposeConnection(pc);
}
}
/**
* Returns the number of active (open) connections of this pool. This is the
* number of <code>Connection</code> objects that have been issued by
* getConnection() for which <code>Connection.close()</code> has
* not yet been called.
*
* @return the number of active connections.
*/
public synchronized int getActiveConnections() {
return activeConnections;
}
}
......@@ -13,13 +13,13 @@ import org.h2.util.StringUtils;
* This class is used by the H2 Console.
*/
public class ConnectionInfo {
String name, driver, url, user;
public String name, driver, url, user;
int lastAccess;
ConnectionInfo() {
}
ConnectionInfo(String data) {
public ConnectionInfo(String data) {
String[] array = StringUtils.arraySplit(data, '|', false);
name = get(array, 0);
driver = get(array, 1);
......
......@@ -70,12 +70,12 @@ public class WebServer implements Service {
"Generic JNDI Data Source|javax.naming.InitialContext|java:comp/env/jdbc/Test|sa",
"Generic Firebird Server|org.firebirdsql.jdbc.FBDriver|jdbc:firebirdsql:localhost:c:/temp/firebird/test|sysdba",
"Generic OneDollarDB|in.co.daffodil.db.jdbc.DaffodilDBDriver|jdbc:daffodilDB_embedded:school;path=C:/temp;create=true|sa",
"Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://<host>/<db>|" ,
"Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@<host>:1521:<instance>|scott" ,
"Generic DB2|COM.ibm.db2.jdbc.net.DB2Driver|jdbc:db2://localhost/test|" ,
"Generic Oracle|oracle.jdbc.driver.OracleDriver|jdbc:oracle:thin:@localhost:1521:test|scott" ,
"Generic MS SQL Server 2000|com.microsoft.jdbc.sqlserver.SQLServerDriver|jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=sqlexpress|sa",
"Generic MS SQL Server 2005|com.microsoft.sqlserver.jdbc.SQLServerDriver|jdbc:sqlserver://localhost;DatabaseName=test|sa",
"Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:<db>|" ,
"Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://<host>:<port>/<db>|" ,
"Generic PostgreSQL|org.postgresql.Driver|jdbc:postgresql:test|" ,
"Generic MySQL|com.mysql.jdbc.Driver|jdbc:mysql://localhost:3306/test|" ,
"Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa" ,
"Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa",
"Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa",
......
......@@ -833,7 +833,9 @@ public class Recover implements DataHandler {
Map.Entry entry = (Entry) it.next();
Integer objectId = (Integer) entry.getKey();
String name = (String) entry.getValue();
writer.println("INSERT INTO " + name + " SELECT * FROM O_" + objectId + ";");
if (objectIdSet.contains(objectId)) {
writer.println("INSERT INTO " + name + " SELECT * FROM O_" + objectId + ";");
}
}
for (Iterator it = objectIdSet.iterator(); it.hasNext();) {
Integer objectId = (Integer) it.next();
......
......@@ -47,8 +47,8 @@ public class RunScript {
* <li>-user username </li>
* <li>-password password </li>
* <li>-script filename (default file name is backup.sql) </li>
* <li>-driver driver the JDBC driver class name (not required for H2)
* </li>
* <li>-driver driver the JDBC driver class name (not required for most
* databases) </li>
* <li>-options to specify a list of options (only for H2 and only when
* using the embedded mode) </li>
* </ul>
......@@ -120,16 +120,13 @@ public class RunScript {
return;
}
long time = System.currentTimeMillis();
// for(int i=0; i<10; i++) {
// int test;
if (options != null) {
executeRunscript(url, user, password, script, options);
} else {
execute(url, user, password, script, null, continueOnError);
}
// }
time = System.currentTimeMillis() - time;
if (showTime) {
time = System.currentTimeMillis() - time;
System.out.println("Done in " + time + " ms");
}
}
......
......@@ -9,30 +9,50 @@ package org.h2.util;
* This class tries to automatically load the right JDBC driver for a given
* database URL.
*/
public class JdbcDriverLoader {
public class JdbcDriverUtils {
private static final String[] DRIVERS = {
"jdbc:h2:", "org.h2.Driver",
"jdbc:firebirdsql:", "org.firebirdsql.jdbc.FBDriver",
"jdbc:Cache:", "com.intersys.jdbc.CacheDriver",
"jdbc:daffodilDB://", "in.co.daffodil.db.rmi.RmiDaffodilDBDriver",
"jdbc:daffodil", "in.co.daffodil.db.jdbc.DaffodilDBDriver",
"jdbc:db2:", "COM.ibm.db2.jdbc.net.DB2Driver",
"jdbc:oracle:", "oracle.jdbc.driver.OracleDriver",
"jdbc:microsoft:", "com.microsoft.jdbc.sqlserver.SQLServerDriver",
"jdbc:sqlserver:", "com.microsoft.sqlserver.jdbc.SQLServerDriver",
"jdbc:postgresql:", "org.postgresql.Driver",
"jdbc:mysql:", "com.mysql.jdbc.Driver",
"jdbc:derby:net:", "org.apache.derby.jdbc.ClientDriver",
"jdbc:derby://", "org.apache.derby.jdbc.ClientDriver",
"jdbc:derby:", "org.apache.derby.jdbc.EmbeddedDriver",
"jdbc:hsqldb:", "org.hsqldb.jdbcDriver"
"jdbc:FrontBase:", "com.frontbase.jdbc.FBJDriver",
"jdbc:firebirdsql:", "org.firebirdsql.jdbc.FBDriver",
"jdbc:hsqldb:", "org.hsqldb.jdbcDriver",
"jdbc:informix-sqli:", "com.informix.jdbc.IfxDriver",
"jdbc:jtds:", "net.sourceforge.jtds.jdbc.Driver",
"jdbc:microsoft:", "com.microsoft.jdbc.sqlserver.SQLServerDriver",
"jdbc:mimer:", "com.mimer.jdbc.Driver",
"jdbc:mysql:", "com.mysql.jdbc.Driver",
"jdbc:odbc:", "sun.jdbc.odbc.JdbcOdbcDriver",
"jdbc:oracle:", "oracle.jdbc.driver.OracleDriver",
"jdbc:pervasive:", "com.pervasive.jdbc.v2.Driver",
"jdbc:pointbase:micro:", "com.pointbase.me.jdbc.jdbcDriver",
"jdbc:pointbase:", "com.pointbase.jdbc.jdbcUniversalDriver",
"jdbc:postgresql:", "org.postgresql.Driver",
"jdbc:sybase:", "com.sybase.jdbc3.jdbc.SybDriver",
"jdbc:sqlserver:", "com.microsoft.sqlserver.jdbc.SQLServerDriver",
};
public static void load(String url) throws ClassNotFoundException {
public static String getDriver(String url) {
for (int i = 0; i < DRIVERS.length; i += 2) {
String prefix = DRIVERS[i];
if (url.startsWith(prefix)) {
Class.forName(DRIVERS[i + 1]);
break;
return DRIVERS[i + 1];
}
}
return null;
}
public static void load(String url) throws ClassNotFoundException {
String driver = getDriver(url);
if (driver != null) {
Class.forName(driver);
}
}
}
......@@ -96,7 +96,7 @@ public class JdbcUtils {
public static Connection getConnection(String driver, String url, Properties prop) throws SQLException {
try {
if (StringUtils.isNullOrEmpty(driver)) {
JdbcDriverLoader.load(url);
JdbcDriverUtils.load(url);
} else {
Class d = ClassUtils.loadUserClass(driver);
if (java.sql.Driver.class.isAssignableFrom(d)) {
......
......@@ -63,6 +63,7 @@ import org.h2.test.jdbc.TestStatement;
import org.h2.test.jdbc.TestTransactionIsolation;
import org.h2.test.jdbc.TestUpdatableResultSet;
import org.h2.test.jdbc.TestZloty;
import org.h2.test.jdbcx.TestConnectionPool;
import org.h2.test.jdbcx.TestDataSource;
import org.h2.test.jdbcx.TestXA;
import org.h2.test.jdbcx.TestXASimple;
......@@ -164,15 +165,6 @@ write to system table before adding to internal data structures
MiniConnectionPoolManager
Hi,
Thanks a lot for your help! I can now also reproduce this problem. It only happens when using LOG=2,
and deleting or updating all rows of a table. There is a workaround (beside not using LOG=1):
System.setProperty("h2.reuseSpaceQuickly", "false");
or java -Dh2.reuseSpaceQuickly=false
I will fix this for the next release.
Regards,
Thomas
--------------
scheduler: what if invoke takes more than...
......@@ -232,7 +224,8 @@ Can sometimes not delete log file? need test case
Add where required // TODO: change in version 1.1
History:
A first (experimental) implementation of a Shell tools is now included (org.h2.tools.Shell).
A new Shell tools is now included (org.h2.tools.Shell) query a
database from the command line.
Performance was very slow when using LOG=2 and deleting or
updating all rows of a table in a loop. Fixed.
ALTER TABLE or CREATE TABLE now support parameters for the password field.
......@@ -244,19 +237,13 @@ Fulltext search (native implementation): The words table is no longer
an in-memory table because this caused memory problems in some cases.
It was possible to create a role with the name as an existing user
(but not vice versa). This is not allowed any more.
The recovery tool didn't work correctly for tables without rows.
Roadmap:
SET LOG_SYSTEM {NATIVE|LOG4J|COMMONS|DRIVER_MANAGER}
Fluent API for tools: Server.createTcpServer().setPort(9081).setPassword(password).start();
console features:
- reset?
- use StringBuffer to append (copy and paste problems)
- password mask option
- result set: two modes (list and table)
- Show Tables of MySQL and Show Fields (also ij)
(not required for H2) > not required for most databases
SET LOG_SYSTEM
{NATIVE|LOG4J|COMMONS|DRIVER_MANAGER}
Fluent API for tools: Server.createTcpServer().
setPort(9081).setPassword(password).start();
*/
......@@ -519,6 +506,7 @@ console features:
new TestZloty().runTest(this);
// jdbcx
new TestConnectionPool().runTest(this);
new TestDataSource().runTest(this);
new TestXA().runTest(this);
new TestXASimple().runTest(this);
......
......@@ -12,7 +12,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.HashMap;
import org.h2.util.JdbcDriverLoader;
import org.h2.util.JdbcDriverUtils;
/**
* A simple wrapper around the JDBC API.
......@@ -31,7 +31,7 @@ public class Db {
public static Db open(String url, String user, String password) {
try {
JdbcDriverLoader.load(url);
JdbcDriverUtils.load(url);
return new Db(DriverManager.getConnection(url, user, password));
} catch (Exception e) {
throw convert(e);
......
package org.h2.test.jdbcx;
import java.sql.Connection;
import java.sql.Statement;
import org.h2.jdbcx.JdbcConnectionPoolManager;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.test.TestBase;
public class TestConnectionPool extends TestBase {
public void test() throws Exception {
deleteDb("connectionPool");
testConnect();
testThreads();
}
private void testThreads() throws Exception {
final int len = getSize(4, 20);
final JdbcConnectionPoolManager man = getConnectionPool(len - 2);
final boolean[] stop = new boolean[1];
class TestRunner implements Runnable {
public void run() {
try {
while (!stop[0]) {
Connection conn = man.getConnection();
checkSmaller(man.getActiveConnections(), len + 1);
Statement stat = conn.createStatement();
stat.execute("SELECT 1 FROM DUAL");
conn.close();
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thread[] threads = new Thread[len];
for (int i = 0; i < len; i++) {
threads[i] = new Thread(new TestRunner());
threads[i].start();
}
Thread.sleep(1000);
stop[0] = true;
for (int i = 0; i < len; i++) {
threads[i].join();
}
check(0, man.getActiveConnections());
man.dispose();
}
JdbcConnectionPoolManager getConnectionPool(int poolSize) throws Exception {
JdbcDataSource ds = new JdbcDataSource();
ds.setURL(getURL("connectionPool", true));
ds.setUser(getUser());
ds.setPassword(getPassword());
return new JdbcConnectionPoolManager(ds, poolSize, 2);
}
private void testConnect() throws Exception {
JdbcConnectionPoolManager man = getConnectionPool(3);
for (int i = 0; i < 100; i++) {
Connection conn = man.getConnection();
conn.close();
}
man.dispose();
}
}
......@@ -244,6 +244,7 @@ public class TestTools extends TestBase {
Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar, b blob, c clob)");
stat.execute("create table test2(id int primary key, name varchar)");
stat.execute("insert into test values(1, 'Hello', SECURE_RAND(2000), space(2000))");
ResultSet rs;
rs = stat.executeQuery("select * from test");
......@@ -257,6 +258,8 @@ public class TestTools extends TestBase {
conn = DriverManager.getConnection(url, "another", "another");
stat = conn.createStatement();
stat.execute("runscript from '" + baseDir + "/toolsRecover.data.sql'");
rs = stat.executeQuery("select * from test2");
checkFalse(rs.next());
rs = stat.executeQuery("select * from test");
rs.next();
check(1, rs.getInt(1));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论