提交 1cdec2b8 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 c77b7023
...@@ -249,6 +249,11 @@ Phase-6</a><br /> ...@@ -249,6 +249,11 @@ Phase-6</a><br />
A computer based learning software. A computer based learning software.
</p> </p>
<p><a href="http://code.google.com/p/pickle4j">
Pickle</a><br />
Pickle is a Java library containing classes for persistence, concurrency, and logging.
</p>
<p><a href="http://www.polepos.org"> <p><a href="http://www.polepos.org">
PolePosition</a><br /> PolePosition</a><br />
Open source database benchmark. Open source database benchmark.
......
...@@ -57,7 +57,7 @@ Roadmap ...@@ -57,7 +57,7 @@ Roadmap
</li><li>Procedural language / script language (Javascript) </li><li>Procedural language / script language (Javascript)
</li><li>Change LOB mechanism (less files, keep index of lob files, point to files and row, delete unused files earlier, maybe bundle files into a tar file) </li><li>Change LOB mechanism (less files, keep index of lob files, point to files and row, delete unused files earlier, maybe bundle files into a tar file)
</li><li>Clustering: recovery needs to becomes fully automatic. Global write lock feature. </li><li>Clustering: recovery needs to becomes fully automatic. Global write lock feature.
</li><li>Option for Java functions: constant/isDeterministic to allow early evaluation when all parameters are constant </li><li>Option for Java functions: constant/isDeterministic/readonly/pure (always return the same value) to allow early evaluation when all parameters are constant
</li><li>Support function overloading as in Java (multiple functions with the same name, but different parameter count or data types) </li><li>Support function overloading as in Java (multiple functions with the same name, but different parameter count or data types)
</li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED) </li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED)
</li><li>Groovy Stored Procedures (http://groovy.codehaus.org/Groovy+SQL) </li><li>Groovy Stored Procedures (http://groovy.codehaus.org/Groovy+SQL)
...@@ -65,8 +65,6 @@ Roadmap ...@@ -65,8 +65,6 @@ Roadmap
</li><li>Add a migration guide (list differences between databases) </li><li>Add a migration guide (list differences between databases)
</li><li>Optimization: automatic index creation suggestion using the trace file? </li><li>Optimization: automatic index creation suggestion using the trace file?
</li><li>Compression performance: don't allocate buffers, compress / expand in to out buffer </li><li>Compression performance: don't allocate buffers, compress / expand in to out buffer
</li><li>Connection pool manager
</li><li>Implement Statement.cancel for server connections
</li><li>Start / stop server with database URL </li><li>Start / stop server with database URL
</li><li>Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE </li><li>Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE
</li><li>Rebuild index functionality (other than delete the index file) </li><li>Rebuild index functionality (other than delete the index file)
...@@ -79,16 +77,15 @@ Roadmap ...@@ -79,16 +77,15 @@ Roadmap
</li><li>Test with dbcopy (http://dbcopyplugin.sourceforge.net) </li><li>Test with dbcopy (http://dbcopyplugin.sourceforge.net)
</li><li>Find a tool to view a text file >100 MB, with find, page up and down (like less) </li><li>Find a tool to view a text file >100 MB, with find, page up and down (like less)
</li><li>Implement, test, document XAConnection and so on </li><li>Implement, test, document XAConnection and so on
</li><li>Web site: meta keywords, description, get rid of frame set </li><li>Web site: get rid of frame set
</li><li>Pluggable data type (for compression, validation, conversion, encryption) </li><li>Pluggable data type (for compression, validation, conversion, encryption)
</li><li>CHECK: find out what makes CHECK=TRUE slow, move to CHECK2 </li><li>CHECK: find out what makes CHECK=TRUE slow, move to CHECK2
</li><li>Improve recovery: improve code for log recovery problems (less try/catch) </li><li>Improve recovery: improve code for log recovery problems (less try/catch)
</li><li>Log linear hash index changes, fast open / close
</li><li>Index usage for (ID, NAME)=(1, 'Hi'); document </li><li>Index usage for (ID, NAME)=(1, 'Hi'); document
</li><li>Suggestion: include jetty as Servlet Container (like LAMP) </li><li>Suggestion: include Jetty as Servlet Container (like LAMP)
</li><li>Trace shipping to server </li><li>Trace shipping to server
</li><li>Performance / server mode: use UDP optionally? </li><li>Performance / server mode: use UDP optionally?
</li><li>Version check: docs / web console (using javascript), and maybe in the library (using TCP/IP) </li><li>Version check: docs / web console (using Javascript), and maybe in the library (using TCP/IP)
</li><li>Web server classloader: override findResource / getResourceFrom </li><li>Web server classloader: override findResource / getResourceFrom
</li><li>Cost for embedded temporary view is calculated wrong, if result is constant </li><li>Cost for embedded temporary view is calculated wrong, if result is constant
</li><li>Comparison: pluggable sort order: natural sort </li><li>Comparison: pluggable sort order: natural sort
...@@ -98,7 +95,6 @@ Roadmap ...@@ -98,7 +95,6 @@ Roadmap
</li><li>iReport to support H2 </li><li>iReport to support H2
</li><li>Implement missing JDBC API (CallableStatement,...) </li><li>Implement missing JDBC API (CallableStatement,...)
</li><li>Compression of the cache </li><li>Compression of the cache
</li><li>Run H2 Console inside servlet (pass-through servlet of fix the JSP / app)
</li><li>Include SMPT (mail) server (at least client) (alert on cluster failure, low disk space,...) </li><li>Include SMPT (mail) server (at least client) (alert on cluster failure, low disk space,...)
</li><li>Drop with restrict (currently cascade is the default) </li><li>Drop with restrict (currently cascade is the default)
</li><li>JSON parser and functions </li><li>JSON parser and functions
...@@ -109,7 +105,6 @@ Roadmap ...@@ -109,7 +105,6 @@ Roadmap
</li><li>Support SET TABLE DUAL READONLY </li><li>Support SET TABLE DUAL READONLY
</li><li>Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files </li><li>Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files
</li><li>Don't write stack traces for common exceptions like duplicate key to the log by default </li><li>Don't write stack traces for common exceptions like duplicate key to the log by default
</li><li>Setting for MAX_QUERY_TIME (default no limit?)
</li><li>GCJ: what is the state now? </li><li>GCJ: what is the state now?
</li><li>Use Janino to convert Java to C++ </li><li>Use Janino to convert Java to C++
</li><li>Reduce disk space usage (Derby uses less disk space?) </li><li>Reduce disk space usage (Derby uses less disk space?)
...@@ -121,11 +116,7 @@ Roadmap ...@@ -121,11 +116,7 @@ Roadmap
</li><li>Custom class loader to reload functions on demand </li><li>Custom class loader to reload functions on demand
</li><li>Test http://mysql-je.sourceforge.net/ </li><li>Test http://mysql-je.sourceforge.net/
</li><li>Close all files when closing the database (including LOB files that are open on the client side) </li><li>Close all files when closing the database (including LOB files that are open on the client side)
</li><li>Test Connection Pool http://jakarta.apache.org/commons/dbcp
</li><li>Profiler option or profiling tool to find long running and often repeated queries (using DatabaseEventListener API)
</li><li>Allow custom settings (@PATH for RUNSCRIPT for example)
</li><li>EXE file: maybe use http://jsmooth.sourceforge.net </li><li>EXE file: maybe use http://jsmooth.sourceforge.net
</li><li>Automatically delete the index file if opening it fails
</li><li>Performance: Automatically build in-memory indexes if the whole table is in memory </li><li>Performance: Automatically build in-memory indexes if the whole table is in memory
</li><li>H2 Console: The webclient could support more features like phpMyAdmin. </li><li>H2 Console: The webclient could support more features like phpMyAdmin.
</li><li>The HELP information schema can be directly exposed in the Console </li><li>The HELP information schema can be directly exposed in the Console
...@@ -138,11 +129,8 @@ Roadmap ...@@ -138,11 +129,8 @@ Roadmap
</li><li>Date: default date is '1970-01-01' (is it 1900-01-01 in the standard / other databases?) </li><li>Date: default date is '1970-01-01' (is it 1900-01-01 in the standard / other databases?)
</li><li>Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID); </li><li>Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID);
</li><li>Max memory rows / max undo log size: use block count / row size not row count </li><li>Max memory rows / max undo log size: use block count / row size not row count
</li><li>Index summary is only written if log=2; maybe write it also when log=1 and everything is fine (and no in doubt transactions)
</li><li>Support 123L syntax as in Java; example: SELECT (2000000000*2) </li><li>Support 123L syntax as in Java; example: SELECT (2000000000*2)
</li><li>Implement point-in-time recovery </li><li>Implement point-in-time recovery
</li><li>Memory database: add a feature to keep named database open until 'shutdown'
</li><li>Use the directory of the first script as the default directory for any scripts run inside that script
</li><li>Include the version name in the jar file name </li><li>Include the version name in the jar file name
</li><li>Optimize ID=? OR ID=?: convert to IN(...) </li><li>Optimize ID=? OR ID=?: convert to IN(...)
</li><li>LIKE: improved version for larger texts (currently using naive search) </li><li>LIKE: improved version for larger texts (currently using naive search)
...@@ -151,7 +139,6 @@ Roadmap ...@@ -151,7 +139,6 @@ Roadmap
</li><li>Automatically convert to the next 'higher' data type whenever there is an overflow. </li><li>Automatically convert to the next 'higher' data type whenever there is an overflow.
</li><li>Throw an exception when the application calls getInt on a Long (optional) </li><li>Throw an exception when the application calls getInt on a Long (optional)
</li><li>Default date format for input and output (local date constants) </li><li>Default date format for input and output (local date constants)
</li><li>Cache collation keys for performance
</li><li>ValueInt.convertToString and so on (remove Value.convertTo) </li><li>ValueInt.convertToString and so on (remove Value.convertTo)
</li><li>Support custom Collators </li><li>Support custom Collators
</li><li>Document ROWNUM usage for reports: SELECT ROWNUM, * FROM (subquery) </li><li>Document ROWNUM usage for reports: SELECT ROWNUM, * FROM (subquery)
...@@ -160,15 +147,9 @@ Roadmap ...@@ -160,15 +147,9 @@ Roadmap
</li><li>Standalone tool to get relevant system properties and add it to the trace output. </li><li>Standalone tool to get relevant system properties and add it to the trace output.
</li><li>Support mixed clustering mode (one embedded, the other server mode) </li><li>Support mixed clustering mode (one embedded, the other server mode)
</li><li>Support 'call proc(1=value)' (PostgreSQL, Oracle) </li><li>Support 'call proc(1=value)' (PostgreSQL, Oracle)
</li><li>HSQLDB compatibility: "INSERT INTO TEST(name) VALUES(?); SELECT IDENTITY()"
</li><li>Shutdown lock (shutdown can only start if there are no logins pending, and logins are delayed until shutdown ends)
</li><li>Automatically delete the index file if opening it fails
</li><li>DbAdapters http://incubator.apache.org/cayenne/
</li><li>JAMon (proxy jdbc driver) </li><li>JAMon (proxy jdbc driver)
</li><li>Console: Allow setting Null value; Alternative display format two column (for copy and paste as well)
</li><li>Console: Improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?) </li><li>Console: Improve editing data (Tab, Shift-Tab, Enter, Up, Down, Shift+Del?)
</li><li>Console: Autocomplete Ctrl+Space inserts template </li><li>Console: Autocomplete Ctrl+Space inserts template
</li><li>Google Code http://code.google.com/p/h2database/issues/list#
</li><li>Simplify translation ('Donate a translation') </li><li>Simplify translation ('Donate a translation')
</li><li>Option to encrypt .trace.db file </li><li>Option to encrypt .trace.db file
</li><li>Write Behind Cache on SATA leads to data corruption See also http://sr5tech.com/write_back_cache_experiments.htm and http://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html </li><li>Write Behind Cache on SATA leads to data corruption See also http://sr5tech.com/write_back_cache_experiments.htm and http://www.jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.html
...@@ -180,7 +161,7 @@ Roadmap ...@@ -180,7 +161,7 @@ Roadmap
</li><li>RANK() and DENSE_RANK(), Partition using OVER() </li><li>RANK() and DENSE_RANK(), Partition using OVER()
</li><li>ROW_NUMBER (not the same as ROWNUM) </li><li>ROW_NUMBER (not the same as ROWNUM)
</li><li>Partial indexing (see PostgreSQL) </li><li>Partial indexing (see PostgreSQL)
</li><li>BUILD should fail if ant test fails </li><li>The build should fail if the test fails
</li><li>http://rubyforge.org/projects/hypersonic/ </li><li>http://rubyforge.org/projects/hypersonic/
</li><li>DbVisualizer profile for H2 </li><li>DbVisualizer profile for H2
</li><li>Add comparator (x === y) : (x = y or (x is null and y is null)) </li><li>Add comparator (x === y) : (x = y or (x is null and y is null))
...@@ -190,7 +171,6 @@ Roadmap ...@@ -190,7 +171,6 @@ Roadmap
</li><li>Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility) </li><li>Table order: ALTER TABLE TEST ORDER BY NAME DESC (MySQL compatibility)
</li><li>Backup tool should work with other databases as well </li><li>Backup tool should work with other databases as well
</li><li>Console: -ifExists doesn't work for the console. Add a flag to disable other dbs </li><li>Console: -ifExists doesn't work for the console. Add a flag to disable other dbs
</li><li>Maybe use Fowler Noll Vo hash function
</li><li>Improved full text search (supports LOBs, reader / tokenizer / filter). </li><li>Improved full text search (supports LOBs, reader / tokenizer / filter).
</li><li>Performance: Update in-place </li><li>Performance: Update in-place
</li><li>Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess) </li><li>Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess)
...@@ -219,44 +199,32 @@ Roadmap ...@@ -219,44 +199,32 @@ Roadmap
</li><li>Improve create index performance </li><li>Improve create index performance
</li><li>Support ARRAY data type </li><li>Support ARRAY data type
</li><li>Implement more JDBC 4.0 features </li><li>Implement more JDBC 4.0 features
</li><li>H2 Console: implement a servlet to allow simple web app integration
</li><li>Support TRANSFORM / PIVOT as in MS Access </li><li>Support TRANSFORM / PIVOT as in MS Access
</li><li>SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...) </li><li>SELECT * FROM (VALUES (...), (...), ....) AS alias(f1, ...)
</li><li>Support updatable views with join on primary keys (to extend a table) </li><li>Support updatable views with join on primary keys (to extend a table)
</li><li>Public interface for functions (not public static) </li><li>Public interface for functions (not public static)
</li><li>Autocomplete: if I type the name of a table that does not exist (should say: syntax not supported) </li><li>Autocomplete: if I type the name of a table that does not exist (should say: syntax not supported)
</li><li>Autocomplete: schema support: "Other Grammar","Table Expression","{[schemaName.]tableName | (select)} [[AS] newTableAlias]
</li><li>Functions: options readonly, deterministic (pure, always return the same value)
</li><li>Document FTP server, including -ftpTask option to execute / kill remote processes </li><li>Document FTP server, including -ftpTask option to execute / kill remote processes
</li><li>Eliminate undo log records if stored on disk (just one pointer per block, not per record) </li><li>Eliminate undo log records if stored on disk (just one pointer per block, not per record)
</li><li>Feature matrix like in <a href="http://www.inetsoftware.de/products/jdbc/mssql/features/default.asp">i-net software</a>. </li><li>Feature matrix like in <a href="http://www.inetsoftware.de/products/jdbc/mssql/features/default.asp">i-net software</a>.
</li><li>Updatable result set on table without primary key or unique index </li><li>Updatable result set on table without primary key or unique index
</li><li>Use LinkedList instead of ArrayList where applicable </li><li>Use LinkedList instead of ArrayList where applicable
</li><li>Optimization: (A=B AND B=C) > (A=B AND B=C AND A=C)
</li><li>Support % operator (modulo) </li><li>Support % operator (modulo)
</li><li>Large subqueries: close them when the main query is closed, not earlier (so result can be reused)
</li><li>Support 1+'2'=3, '1'+'2'='12' (MS SQL Server compatibility) </li><li>Support 1+'2'=3, '1'+'2'='12' (MS SQL Server compatibility)
</li><li>Support nested transactions </li><li>Support nested transactions
</li><li>Add a benchmark for big databases, and one for many users </li><li>Add a benchmark for big databases, and one for many users
</li><li>Compression in the result set (repeating values in the same column) </li><li>Compression in the result set (repeating values in the same column)
</li><li>Improve command line consistency (+/- options, or true false options)
</li><li>Allow to use the catalog name in statements: [[catalog.]schema.]object
</li><li>Support curtimestamp (like curtime, curdate) </li><li>Support curtimestamp (like curtime, curdate)
</li><li>Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options </li><li>Support ANALYZE {TABLE|INDEX} tableName COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options
</li><li>Support Sequoia (Continuent.org) </li><li>Support Sequoia (Continuent.org)
</li><li>Dynamic length numbers / special methods for DataPage.writeByte / writeShort / Ronni Nielsen </li><li>Dynamic length numbers / special methods for DataPage.writeByte / writeShort / Ronni Nielsen
</li><li>Pluggable ThreadPool, (AvalonDB / deebee / Paul Hammant) </li><li>Pluggable ThreadPool, (AvalonDB / deebee / Paul Hammant)
</li><li>Recursive Queries (see details) </li><li>Recursive Queries (see details)
</li><li>Use index on boolean flag (see details) </li><li>Add GUI to build a custom version (embedded, fulltext,...)
</li><li>Add build for embedded database only
</li><li>Release locks (shared or exclusive) on demand </li><li>Release locks (shared or exclusive) on demand
</li><li>Support catalog names
</li><li>Add object id to metadata tables
</li><li>Support OUTER UNION </li><li>Support OUTER UNION
</li><li>Support Parameterized Views (similar to CSVREAD, but using just SQL for the definition) </li><li>Support Parameterized Views (similar to CSVREAD, but using just SQL for the definition)
</li><li>Implement a command line SQL utility similar to HenPlus: http://henplus.sourceforge.net
</li><li>A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object </li><li>A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object
</li><li>Build script for the embedded functionality only (h2embedded.jar)
</li><li>Option for SCRIPT to only process one or a set of tables, and append to a file </li><li>Option for SCRIPT to only process one or a set of tables, and append to a file
</li><li>Support using a unique index for IS NULL (including linked tables) </li><li>Support using a unique index for IS NULL (including linked tables)
</li><li>Support linked tables to the current database </li><li>Support linked tables to the current database
...@@ -269,7 +237,6 @@ Roadmap ...@@ -269,7 +237,6 @@ Roadmap
</li><li>H2 Console / large result sets: use 'streaming' instead of building the page in-memory </li><li>H2 Console / large result sets: use 'streaming' instead of building the page in-memory
</li><li>Benchmark: add a graph to show how databases scale (performance/database size) </li><li>Benchmark: add a graph to show how databases scale (performance/database size)
</li><li>Implement a SQLData interface to map your data over to a custom object </li><li>Implement a SQLData interface to map your data over to a custom object
</li><li>Extend H2 Console to run tools (show command line as well)
</li><li>Make DDL (Data Definition) operations transactional </li><li>Make DDL (Data Definition) operations transactional
</li><li>Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString') </li><li>Allow execution time prepare for SELECT * FROM CSVREAD(?, 'columnNameString')
</li><li>Support multiple directories (on different hard drives) for the same database </li><li>Support multiple directories (on different hard drives) for the same database
......
...@@ -238,10 +238,9 @@ public class CommandRemote implements CommandInterface { ...@@ -238,10 +238,9 @@ public class CommandRemote implements CommandInterface {
/** /**
* Cancel this current statement. * Cancel this current statement.
* This method is not yet implemented for this class.
*/ */
public void cancel() { public void cancel() {
// TODO server: support cancel session.cancelStatement(id);
} }
public String toString() { public String toString() {
......
...@@ -23,6 +23,7 @@ import org.h2.message.TraceSystem; ...@@ -23,6 +23,7 @@ import org.h2.message.TraceSystem;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.store.DataHandler; import org.h2.store.DataHandler;
import org.h2.store.FileStore; import org.h2.store.FileStore;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
...@@ -51,6 +52,8 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -51,6 +52,8 @@ public class SessionRemote implements SessionInterface, DataHandler {
public static final int CHANGE_ID = 9; public static final int CHANGE_ID = 9;
public static final int COMMAND_GET_META_DATA = 10; public static final int COMMAND_GET_META_DATA = 10;
public static final int SESSION_PREPARE_READ_PARAMS = 11; public static final int SESSION_PREPARE_READ_PARAMS = 11;
public static final int SESSION_SET_ID = 12;
public static final int SESSION_CANCEL_STATEMENT = 13;
public static final int STATUS_ERROR = 0; public static final int STATUS_ERROR = 0;
public static final int STATUS_OK = 1; public static final int STATUS_OK = 1;
...@@ -68,12 +71,14 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -68,12 +71,14 @@ public class SessionRemote implements SessionInterface, DataHandler {
private String cipher; private String cipher;
private byte[] fileEncryptionKey; private byte[] fileEncryptionKey;
private Object lobSyncObject = new Object(); private Object lobSyncObject = new Object();
private String sessionId;
private int clientVersion = Constants.TCP_DRIVER_VERSION_5; private int clientVersion = Constants.TCP_DRIVER_VERSION_5;
private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException, SQLException { private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException, SQLException {
Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_SERVER_PORT, ci.isSSL()); Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_SERVER_PORT, ci.isSSL());
Transfer trans = new Transfer(this); Transfer trans = new Transfer(this);
trans.setSocket(socket); trans.setSocket(socket);
trans.setSSL(ci.isSSL());
trans.init(); trans.init();
trans.writeInt(clientVersion); trans.writeInt(clientVersion);
trans.writeString(db); trans.writeString(db);
...@@ -96,6 +101,34 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -96,6 +101,34 @@ public class SessionRemote implements SessionInterface, DataHandler {
autoCommit = true; autoCommit = true;
return trans; return trans;
} }
public void cancel() {
// this method is called when closing the connection
// the statement that is currently running is not cancelled in this case
// however Statement.cancel is supported
}
public void cancelStatement(int id) {
for (int i = 0; i < transferList.size(); i++) {
Transfer transfer = (Transfer) transferList.get(i);
try {
Transfer trans = transfer.openNewConnection();
trans.init();
trans.writeInt(clientVersion);
if (clientVersion >= Constants.TCP_DRIVER_VERSION_6) {
trans.writeInt(clientVersion);
}
trans.writeString(null);
trans.writeString(null);
trans.writeString(sessionId);
trans.writeInt(SessionRemote.SESSION_CANCEL_STATEMENT);
trans.writeInt(id);
trans.close();
} catch (IOException e) {
trace.debug("Could not cancel statement", e);
}
}
}
private void switchOffAutoCommitIfCluster() throws SQLException { private void switchOffAutoCommitIfCluster() throws SQLException {
if (autoCommit && transferList.size() > 1) { if (autoCommit && transferList.size() > 1) {
...@@ -256,6 +289,23 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -256,6 +289,23 @@ public class SessionRemote implements SessionInterface, DataHandler {
trace.error("Error trying to upgrade client version", e); trace.error("Error trying to upgrade client version", e);
// ignore // ignore
} }
if (clientVersion >= Constants.TCP_DRIVER_VERSION_6) {
sessionId = ByteUtils.convertBytesToString(RandomUtils.getSecureBytes(32));
synchronized (this) {
for (int i = 0; i < transferList.size(); i++) {
Transfer transfer = (Transfer) transferList.get(i);
try {
traceOperation("SESSION_SET_ID", 0);
transfer.writeInt(SessionRemote.SESSION_SET_ID);
transfer.writeString(sessionId);
done(transfer);
} catch (Exception e) {
trace.error("sessionSetId", e);
}
}
}
}
} }
private void switchOffCluster() throws SQLException { private void switchOffCluster() throws SQLException {
...@@ -454,11 +504,6 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -454,11 +504,6 @@ public class SessionRemote implements SessionInterface, DataHandler {
return lobSyncObject; return lobSyncObject;
} }
public void cancel() {
// TODO open another remote connection and cancel this session
// using a unique id (like PostgreSQL)
}
public boolean getLobFilesInDirectories() { public boolean getLobFilesInDirectories() {
return false; return false;
} }
......
...@@ -493,10 +493,9 @@ public class JdbcStatement extends TraceObject implements Statement { ...@@ -493,10 +493,9 @@ public class JdbcStatement extends TraceObject implements Statement {
} }
/** /**
* [Partially supported] Cancels a currently running statement. * Cancels a currently running statement.
* This method must be called from within another * This method must be called from within another
* thread than the execute method. * thread than the execute method.
* This method is not supported in the server mode.
* *
* @throws SQLException if this object is closed * @throws SQLException if this object is closed
*/ */
......
...@@ -385,4 +385,14 @@ public class TcpServer implements Service { ...@@ -385,4 +385,14 @@ public class TcpServer implements Service {
} }
} }
public void cancelStatement(String sessionId, int statementId) throws SQLException {
ArrayList list = new ArrayList(running);
for (int i = 0; i < list.size(); i++) {
TcpServerThread c = (TcpServerThread) list.get(i);
if (c != null) {
c.cancelStatement(sessionId, statementId);
}
}
}
} }
...@@ -28,6 +28,7 @@ import org.h2.result.LocalResult; ...@@ -28,6 +28,7 @@ import org.h2.result.LocalResult;
import org.h2.result.ResultColumn; import org.h2.result.ResultColumn;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.SmallMap; import org.h2.util.SmallMap;
import org.h2.util.StringUtils;
import org.h2.value.Transfer; import org.h2.value.Transfer;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -44,6 +45,7 @@ public class TcpServerThread implements Runnable { ...@@ -44,6 +45,7 @@ public class TcpServerThread implements Runnable {
private SmallMap cache = new SmallMap(SysProperties.SERVER_CACHED_OBJECTS); private SmallMap cache = new SmallMap(SysProperties.SERVER_CACHED_OBJECTS);
private int id; private int id;
private int clientVersion; private int clientVersion;
private String sessionId;
public TcpServerThread(Socket socket, TcpServer server, int id) { public TcpServerThread(Socket socket, TcpServer server, int id) {
this.server = server; this.server = server;
...@@ -76,6 +78,15 @@ public class TcpServerThread implements Runnable { ...@@ -76,6 +78,15 @@ public class TcpServerThread implements Runnable {
} }
String db = transfer.readString(); String db = transfer.readString();
String originalURL = transfer.readString(); String originalURL = transfer.readString();
if (db == null && originalURL == null) {
String sessionId = transfer.readString();
int command = transfer.readInt();
stop = true;
if (command == SessionRemote.SESSION_CANCEL_STATEMENT) {
int statementId = transfer.readInt();
server.cancelStatement(sessionId, statementId);
}
}
String baseDir = server.getBaseDir(); String baseDir = server.getBaseDir();
if (baseDir == null) { if (baseDir == null) {
baseDir = SysProperties.getBaseDir(); baseDir = SysProperties.getBaseDir();
...@@ -317,6 +328,11 @@ public class TcpServerThread implements Runnable { ...@@ -317,6 +328,11 @@ public class TcpServerThread implements Runnable {
cache.addObject(newId, obj); cache.addObject(newId, obj);
break; break;
} }
case SessionRemote.SESSION_SET_ID: {
sessionId = transfer.readString();
transfer.writeInt(SessionRemote.STATUS_OK).flush();
break;
}
default: default:
trace("Unknown operation: " + operation); trace("Unknown operation: " + operation);
closeSession(); closeSession();
...@@ -344,4 +360,11 @@ public class TcpServerThread implements Runnable { ...@@ -344,4 +360,11 @@ public class TcpServerThread implements Runnable {
return thread; return thread;
} }
public void cancelStatement(String sessionId, int statementId) throws SQLException {
if (StringUtils.equals(sessionId, this.sessionId)) {
Command cmd = (Command) cache.getObject(statementId, false);
cmd.cancel();
}
}
} }
...@@ -17,6 +17,7 @@ import java.io.OutputStreamWriter; ...@@ -17,6 +17,7 @@ import java.io.OutputStreamWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.sql.Date; import java.sql.Date;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -34,6 +35,7 @@ import org.h2.message.TraceSystem; ...@@ -34,6 +35,7 @@ import org.h2.message.TraceSystem;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.ExactUTF8InputStreamReader; import org.h2.util.ExactUTF8InputStreamReader;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.NetUtils;
import org.h2.util.StringCache; import org.h2.util.StringCache;
/** /**
...@@ -49,6 +51,7 @@ public class Transfer { ...@@ -49,6 +51,7 @@ public class Transfer {
protected Socket socket; protected Socket socket;
protected DataInputStream in; protected DataInputStream in;
protected DataOutputStream out; protected DataOutputStream out;
private boolean ssl;
public Transfer(SessionInterface session) { public Transfer(SessionInterface session) {
this.session = session; this.session = session;
...@@ -413,4 +416,18 @@ public class Transfer { ...@@ -413,4 +416,18 @@ public class Transfer {
this.session = session; this.session = session;
} }
public void setSSL(boolean ssl) {
this.ssl = ssl;
}
public Transfer openNewConnection() throws IOException {
InetAddress address = socket.getInetAddress();
int port = socket.getPort();
Socket socket = NetUtils.createSocket(address, port, ssl);
Transfer trans = new Transfer(null);
trans.setSocket(socket);
trans.setSSL(ssl);
return trans;
}
} }
...@@ -162,6 +162,10 @@ java org.h2.test.TestAll timer ...@@ -162,6 +162,10 @@ java org.h2.test.TestAll timer
improve javadocs improve javadocs
Shell / JDK 1.6: use java.io.Console
</li><li>Implement Statement.cancel for server connections
upload jazoon upload jazoon
test case for out of memory (try to corrupt the database using out of memory) test case for out of memory (try to corrupt the database using out of memory)
...@@ -211,6 +215,8 @@ Add where required // TODO: change in version 1.1 ...@@ -211,6 +215,8 @@ Add where required // TODO: change in version 1.1
http://www.w3schools.com/sql/ http://www.w3schools.com/sql/
History: History:
Statements can now be cancelled remotely
(when using remote connections).
Roadmap: Roadmap:
...@@ -412,7 +418,6 @@ Roadmap: ...@@ -412,7 +418,6 @@ Roadmap:
* Run all tests with the current settings. * Run all tests with the current settings.
*/ */
private void test() throws Exception { private void test() throws Exception {
System.out.println(); System.out.println();
System.out.println("Test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc + " deleteIndex:" + deleteIndex); System.out.println("Test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc + " deleteIndex:" + deleteIndex);
beforeTest(); beforeTest();
......
...@@ -16,30 +16,38 @@ import org.h2.constant.ErrorCode; ...@@ -16,30 +16,38 @@ import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
* Tests Statement.cancel * Tests Statement.cancel
*/ */
public class TestCancel extends TestBase { public class TestCancel extends TestBase {
private static int lastVisited;
class CancelThread extends Thread { class CancelThread extends Thread {
private Statement cancel; private Statement cancel;
private int wait; private int wait;
private volatile boolean stop;
CancelThread(Statement cancel, int wait) { CancelThread(Statement cancel, int wait) {
this.cancel = cancel; this.cancel = cancel;
this.wait = wait; this.wait = wait;
} }
public void stopNow() {
this.stop = true;
}
public void run() { public void run() {
try { while (!stop) {
Thread.sleep(wait); try {
cancel.cancel(); Thread.sleep(wait);
Thread.yield(); cancel.cancel();
} catch (SQLException e) { Thread.yield();
// ignore errors on closed statements } catch (SQLException e) {
} catch (Exception e) { // ignore errors on closed statements
TestBase.logError("sleep", e); } catch (Exception e) {
TestBase.logError("sleep", e);
}
} }
} }
} }
...@@ -124,16 +132,22 @@ public class TestCancel extends TestBase { ...@@ -124,16 +132,22 @@ public class TestCancel extends TestBase {
System.setProperty("h2.maxQueryTimeout", "" + oldMax); System.setProperty("h2.maxQueryTimeout", "" + oldMax);
} }
} }
public static int visit(int x) {
lastVisited = x;
return x;
}
private void testCancelStatement() throws Exception { private void testCancelStatement() throws Exception {
deleteDb("cancel"); deleteDb("cancel");
Connection conn = getConnection("cancel"); Connection conn = getConnection("cancel");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("DROP TABLE IF EXISTS TEST"); stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE ALIAS VISIT FOR \"" + getClass().getName() + ".visit\"");
stat.execute("CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"); stat.execute("CREATE MEMORY TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)"); PreparedStatement prep = conn.prepareStatement("INSERT INTO TEST VALUES(?, ?)");
trace("insert"); trace("insert");
int len = getSize(1, 1000); int len = getSize(10, 1000);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
prep.setInt(1, i); prep.setInt(1, i);
// prep.setString(2, "Test Value "+i); // prep.setString(2, "Test Value "+i);
...@@ -145,23 +159,21 @@ public class TestCancel extends TestBase { ...@@ -145,23 +159,21 @@ public class TestCancel extends TestBase {
for (int i = 1;;) { for (int i = 1;;) {
Statement query = conn.createStatement(); Statement query = conn.createStatement();
CancelThread cancel = new CancelThread(query, i); CancelThread cancel = new CancelThread(query, i);
visit(0);
cancel.start(); cancel.start();
Thread.yield(); Thread.yield();
int j = 0;
try { try {
ResultSet rs = query.executeQuery("SELECT * FROM TEST"); query.executeQuery(
while (rs.next()) { "SELECT VISIT(ID), (SELECT SUM(X) FROM SYSTEM_RANGE(1, 10000) WHERE X<>ID) FROM TEST ORDER BY ID");
j++;
}
trace("record count: " + j);
} catch (SQLException e) { } catch (SQLException e) {
checkNotGeneralException(e); checkNotGeneralException(e);
// ignore cancelled statements // ignore cancelled statements
trace("record count: " + j);
} }
if (j == 0) { cancel.stopNow();
cancel.join();
if (lastVisited == 0) {
i += 10; i += 10;
} else if (j == len) { } else {
break; break;
} }
} }
......
...@@ -28,6 +28,7 @@ To use the same default settings as H2, use: ...@@ -28,6 +28,7 @@ To use the same default settings as H2, use:
jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true
Also, you need to execute the following statement: Also, you need to execute the following statement:
SET WRITE_DELAY 1 SET WRITE_DELAY 1
No optimization for COUNT(*)
Derby Derby
...@@ -38,3 +39,4 @@ See ...@@ -38,3 +39,4 @@ See
http://db.apache.org/derby/javadoc/engine/org/apache/derby/iapi/reference/Property.html#FILESYNC_TRANSACTION_LOG http://db.apache.org/derby/javadoc/engine/org/apache/derby/iapi/reference/Property.html#FILESYNC_TRANSACTION_LOG
Missing features: Missing features:
LIMIT OFFSET is not supported. LIMIT OFFSET is not supported.
No optimization for COUNT(*)
...@@ -508,4 +508,5 @@ informs negotiations collectively omissions trial nor qualify steward neither ...@@ -508,4 +508,5 @@ informs negotiations collectively omissions trial nor qualify steward neither
worldwide everyone additions expense lawsuit checksums jazoon flashback worldwide everyone additions expense lawsuit checksums jazoon flashback
dieguez dfile mvn dversion dgroup dpackaging dartifact durl dpom pom dieguez dfile mvn dversion dgroup dpackaging dartifact durl dpom pom
subpackages slowed deactivate throttled noindex expired arizona export subpackages slowed deactivate throttled noindex expired arizona export
intentional knowing jcl plug facade deployment logback confusion intentional knowing jcl plug facade deployment logback confusion visited
pickle
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论