提交 9cf66529 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 433bf879
...@@ -11,7 +11,7 @@ Advanced Topics ...@@ -11,7 +11,7 @@ Advanced Topics
<table class="content"><tr class="content"><td class="content"><div class="contentDiv"> <table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>Advanced Topics</h1> <h1>Advanced Topics</h1>
<a href="#resultsets"> <a href="#result_sets">
Result Sets</a><br> Result Sets</a><br>
<a href="#large_objects"> <a href="#large_objects">
Large Objects</a><br> Large Objects</a><br>
...@@ -46,7 +46,7 @@ Advanced Topics ...@@ -46,7 +46,7 @@ Advanced Topics
<a href="#glossary_links"> <a href="#glossary_links">
Glossary and Links</a><br> Glossary and Links</a><br>
<br><a name="resultsets"></a> <br><a name="result_sets"></a>
<h2>Result Sets</h2> <h2>Result Sets</h2>
<h3>Limiting the Number of Rows</h3> <h3>Limiting the Number of Rows</h3>
...@@ -85,7 +85,7 @@ CREATE LINKED TABLE LINK('org.postgresql.Driver', 'jdbc:postgresql:test', 'sa', ...@@ -85,7 +85,7 @@ CREATE LINKED TABLE LINK('org.postgresql.Driver', 'jdbc:postgresql:test', 'sa',
</pre> </pre>
It is then possible to access the table in the usual way. It is then possible to access the table in the usual way.
There is a restriction when inserting data to this table: When inserting or updating rows into the table, There is a restriction when inserting data to this table: When inserting or updating rows into the table,
NULL values and values that are not set in the insert statement are both inserted as NULL. NULL and values that are not set in the insert statement are both inserted as NULL.
This may not have the desired effect if a default value in the target table is other than NULL. This may not have the desired effect if a default value in the target table is other than NULL.
<br><a name="transaction_isolation"></a> <br><a name="transaction_isolation"></a>
...@@ -358,7 +358,7 @@ In Java, there are two ways how this can be achieved: ...@@ -358,7 +358,7 @@ In Java, there are two ways how this can be achieved:
</p> </p>
<ul> <ul>
<li>FileDescriptor.sync(). The documentation says that this will force all system buffers to synchronize with the underlying device. <li>FileDescriptor.sync(). The documentation says that this will force all system buffers to synchronize with the underlying device.
Sync is supposed to return after all in-memory modified copies of buffers associated with this FileDesecriptor Sync is supposed to return after all in-memory modified copies of buffers associated with this FileDescriptor
have been written to the physical medium. have been written to the physical medium.
<li>FileChannel.force() (since JDK 1.4). This method is supposed to force any updates to this channel's file <li>FileChannel.force() (since JDK 1.4). This method is supposed to force any updates to this channel's file
to be written to the storage device that contains it. to be written to the storage device that contains it.
...@@ -643,7 +643,7 @@ custom certificates are supported as well. ...@@ -643,7 +643,7 @@ custom certificates are supported as well.
<br><a name="uuid"></a> <br><a name="uuid"></a>
<h2>Universally Unique Identifiers (UUID)</h2> <h2>Universally Unique Identifiers (UUID)</h2>
This database supports UUIDs. Also upported is a function to create new UUIDs using This database supports the UUIDs. Also supported is a function to create new UUIDs using
a cryptographically strong pseudo random number generator. a cryptographically strong pseudo random number generator.
With random UUIDs, the chance of two having the same value can be calculated With random UUIDs, the chance of two having the same value can be calculated
using the probability theory. See also 'Birthday Paradox'. using the probability theory. See also 'Birthday Paradox'.
......
...@@ -14,10 +14,8 @@ Frequently Asked Questions ...@@ -14,10 +14,8 @@ Frequently Asked Questions
<h3>Are there any known bugs? When is the next release?</h3> <h3>Are there any known bugs? When is the next release?</h3>
Usually, bugs get fixes as they are found. There is a release every few weeks. Usually, bugs get fixes as they are found. There is a release every few weeks.
The next release is planned for
2007-01-29.
Here is the list of known and confirmed issues as of Here is the list of known and confirmed issues as of
2007-01-17: 2007-01-30:
<ul> <ul>
<li>Can not build using ant with JDK 1.3 at the moment. However most things are fixed. <li>Can not build using ant with JDK 1.3 at the moment. However most things are fixed.
<li>Some problems have been found with right outer join. Internally, it is converted to left outer join, which <li>Some problems have been found with right outer join. Internally, it is converted to left outer join, which
...@@ -43,7 +41,7 @@ some problems that have not yet been found. ...@@ -43,7 +41,7 @@ some problems that have not yet been found.
Areas that are not completely tested: Areas that are not completely tested:
<ul> <ul>
<li>Platforms other than Windows XP and the Sun JVM 1.4 <li>Platforms other than Windows XP and the Sun JVM 1.4
<li>Data types BLOBs / CLOBs, VARCHAR_IGNORECASE, OTHER <li>Data types BLOB, CLOB, VARCHAR_IGNORECASE, OTHER
<li>Cluster mode, 2-Phase Commit, Savepoints <li>Cluster mode, 2-Phase Commit, Savepoints
<li>Server mode (well tested, but not as well as Embedded mode) <li>Server mode (well tested, but not as well as Embedded mode)
<li>Multi-Threading and using multiple connections <li>Multi-Threading and using multiple connections
......
...@@ -349,7 +349,7 @@ This is achieved using different database URLs. The settings in the URLs are not ...@@ -349,7 +349,7 @@ This is achieved using different database URLs. The settings in the URLs are not
<td>In-Memory (named)</td> <td>In-Memory (named)</td>
<td> <td>
jdbc:h2:mem:&lt;databaseName&gt;<br> jdbc:h2:mem:&lt;databaseName&gt;<br>
jdbc:h2:mem:imdb1 jdbc:h2:mem:test_mem
</td> </td>
</tr> </tr>
<tr> <tr>
...@@ -816,14 +816,14 @@ Here is the list of currently supported modes and the difference to the regular ...@@ -816,14 +816,14 @@ Here is the list of currently supported modes and the difference to the regular
<tr><td> <tr><td>
PostgreSQL PostgreSQL
</td><td> </td><td>
Concatenation of a NULL value with another value results in NULL. Concatenation of a NULL with another value results in NULL.
Usually, the NULL is treated as an empty string if only one of the operators is NULL, Usually, the NULL is treated as an empty string if only one of the operators is NULL,
and NULL is only returned if both values are NULL. and NULL is only returned if both values are NULL.
</td></tr> </td></tr>
<tr><td> <tr><td>
MySQL MySQL
</td><td> </td><td>
When inserting data, if a column is defined to be NOT NULL and a null value is inserted, When inserting data, if a column is defined to be NOT NULL and NULL is inserted,
then a 0 (or empty string, or the current timestamp for timestamp columns) value is used. then a 0 (or empty string, or the current timestamp for timestamp columns) value is used.
Usually, this operation is not allowed and an exception is thrown. Usually, this operation is not allowed and an exception is thrown.
</td></tr> </td></tr>
...@@ -1024,7 +1024,7 @@ secure. A way to create good passwords that can be remembered is, take the first ...@@ -1024,7 +1024,7 @@ secure. A way to create good passwords that can be remembered is, take the first
letters of a sentence, use upper and lower case characters, and creatively include special characters. letters of a sentence, use upper and lower case characters, and creatively include special characters.
Example: Example:
</p><p> </p><p>
i'sE2rTpiUKtt (it's easy to remember this password if you know the trick) i'sE2rtPiUKtT (it's easy to remember this password if you know the trick)
</p> </p>
<h3>Passwords: Using Char Arrays instead of Strings</h3> <h3>Passwords: Using Char Arrays instead of Strings</h3>
...@@ -1096,7 +1096,7 @@ public class Function { ...@@ -1096,7 +1096,7 @@ public class Function {
</pre> </pre>
The Java function must be registered in the database by calling CREATE ALIAS: The Java function must be registered in the database by calling CREATE ALIAS:
<pre> <pre>
CREATE ALIAS ISPRIME FOR "org.h2.samples.Function.isPrime" CREATE ALIAS IS_PRIME FOR "org.h2.samples.Function.isPrime"
</pre> </pre>
For a complete sample application, see src/test/org/h2/samples/Function.java. For a complete sample application, see src/test/org/h2/samples/Function.java.
......
...@@ -36,7 +36,19 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -36,7 +36,19 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3> <h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / TODO</h3><ul> <h3>Version 1.0 / 2007-01-30</h3><ul>
<li>Experimental online backup feature using the SQL statement BACKUP TO 'fileName'.
This creates a backup in the form of a zip file. Unlike the SCRIPT TO command, the data tables are not locked.
<li>When using the server mode, temporary files for large LOB values are now deleted when the result set is closed.
This also means that LOBs become unavailable after closing the result, however this is according to the specs.
<li>It was possible that SUM throws a class cast exception if the parameter was a conditional expression.
<li>Benchmark: Added a multi-client test case, BenchB (similar to TPC-B).
<li>Compatibility: SCHEMA_NAME.SEQUENCE_NAME.NEXTVAL now works as expected.
<li>The Console is now translated to Hungarian thanks to Andras Hideg,
and to Indonesian thanks to Joko Yuliantoro
<li>XAConnection: A NullPointerException was thrown if addConnectionEventListener was called before opening the connection.
<li>In case the result set of a subquery was re-used, an exception was throws if the subquery result did not fit in memory.
Now the result is not re-used in this case. Generally, large subqueries should be avoided for performance reasons.
<li>The command "drop all objects delete files" did not work on linux if the database name was lower case. <li>The command "drop all objects delete files" did not work on linux if the database name was lower case.
<li>When setting the URL to an empty string the DataSource now throws an better exception. <li>When setting the URL to an empty string the DataSource now throws an better exception.
<li>Parsing of LIKE .. ESCAPE did not stop at the expected point. Fixed. <li>Parsing of LIKE .. ESCAPE did not stop at the expected point. Fixed.
...@@ -55,7 +67,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -55,7 +67,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Fixed a problem where data in the log file was not written to the data file (recovery failure) after a crash, <li>Fixed a problem where data in the log file was not written to the data file (recovery failure) after a crash,
if an index was deleted previously. if an index was deleted previously.
<li>SCRIPT NODATA now writes the row count for each table (this simplifies comparing databases). <li>SCRIPT NODATA now writes the row count for each table (this simplifies comparing databases).
<li>Selecting a column using the syntax schemaName.tableName.columName did not work in all cases. <li>Selecting a column using the syntax schemaName.tableName.columnName did not work in all cases.
<li>Can now parse timestamps with timezone information (Z or +/-hh:mm) and dates before year 1. <li>Can now parse timestamps with timezone information (Z or +/-hh:mm) and dates before year 1.
However dates before year 1 are not formatted correctly (this is a Java problem). However dates before year 1 are not formatted correctly (this is a Java problem).
<li>When stopping the TCP server from an application and immediately afterwards staring it again <li>When stopping the TCP server from an application and immediately afterwards staring it again
...@@ -70,7 +82,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -70,7 +82,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 / 2007-01-02</h3><ul> <h3>Version 1.0 / 2007-01-02</h3><ul>
<li>It was possible to drop the sequence of a temporary tables with DROP ALL OBJECTS, resulting in a null pointer exception afterwards. <li>It was possible to drop the sequence of a temporary tables with DROP ALL OBJECTS, resulting in a null pointer exception afterwards.
<li>Prepardd statements with non-constant functions such as CURRENT_TIMESTAMP() did not get re-evaluated if the result of the function changed. Fixed. <li>Prepared statements with non-constant functions such as CURRENT_TIMESTAMP() did not get re-evaluated if the result of the function changed. Fixed.
<li>The (relative or absolute) directory where the script files are stored or read can now be changed using the system property h2.scriptDirectory <li>The (relative or absolute) directory where the script files are stored or read can now be changed using the system property h2.scriptDirectory
<li>Client trace files now created in the directory 'trace.db' and no longer the application directory. <li>Client trace files now created in the directory 'trace.db' and no longer the application directory.
This can be changed using the system property h2.clientTraceDirectory. This can be changed using the system property h2.clientTraceDirectory.
...@@ -103,7 +115,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -103,7 +115,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
earlier. earlier.
<li>Opening a large database is now much faster when even when using the default log mode (LOG=1), <li>Opening a large database is now much faster when even when using the default log mode (LOG=1),
if the database was closed previously. if the database was closed previously.
<li>Very large BLOBs and CLOBs can now be used with the server and the cluster mode. <li>Very large BLOB and CLOB data can now be used with the server and the cluster mode.
The objects will temporarily be buffered on the client side if they are larger than some The objects will temporarily be buffered on the client side if they are larger than some
size (currently 64 KB). size (currently 64 KB).
<li>PreparedStatement.setObject(x, y, Types.OTHER) does now serialize the object in every case <li>PreparedStatement.setObject(x, y, Types.OTHER) does now serialize the object in every case
...@@ -143,10 +155,10 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -143,10 +155,10 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</ul> </ul>
<h3>Version 1.0 / 2006-11-20</h3><ul> <h3>Version 1.0 / 2006-11-20</h3><ul>
<li>SCRIPT: New option BLOCKSIZE to split BLOBs and CLOBs into separate blocks, to avoid OutOfMemory problems. <li>SCRIPT: New option BLOCKSIZE to split BLOB and CLOB data into separate blocks, to avoid OutOfMemory problems.
<li>When using the READ_COMMITTED isolation level, a transaction now waits until there are no write locks <li>When using the READ_COMMITTED isolation level, a transaction now waits until there are no write locks
when trying to read data. However, it still does not add a read lock. when trying to read data. However, it still does not add a read lock.
<li>INSERT INTO ... SELECT ... and ALTER TABLE with CLOBs and/or BLOBs did not work. Fixed. <li>INSERT INTO ... SELECT ... and ALTER TABLE with CLOB and/or BLOB did not work. Fixed.
<li>CSV tool: the methods setFieldSeparatorWrite and setRowSeparatorWrite where not accessible. <li>CSV tool: the methods setFieldSeparatorWrite and setRowSeparatorWrite where not accessible.
The API has been changed, there is now only one static method, getInstance(). The API has been changed, there is now only one static method, getInstance().
<li>ALTER TABLE ADD did throw a strange message if the table contained views. Now the message is better, <li>ALTER TABLE ADD did throw a strange message if the table contained views. Now the message is better,
...@@ -257,7 +269,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -257,7 +269,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
was not correctly synchronized. Fixed. was not correctly synchronized. Fixed.
<li> <li>
Function aliases may optionally include parameter classes. Example: Function aliases may optionally include parameter classes. Example:
CREATE ALIAS PARSEINT2 FOR "java.lang.Integer.parseInt(java.lang.String, int)" CREATE ALIAS PARSE_INT2 FOR "java.lang.Integer.parseInt(java.lang.String, int)"
<li> <li>
Support for UUID Support for UUID
<li> <li>
...@@ -565,7 +577,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -565,7 +577,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li> <li>
Compatibility: SUBSTRING(string FROM start FOR length) Compatibility: SUBSTRING(string FROM start FOR length)
<li> <li>
CREATE VIEW now supports a column list: CREATE VIEW TESTV(A, B) AS ... CREATE VIEW now supports a column list: CREATE VIEW TEST_V(A, B) AS ...
<li> <li>
Compatibility: 'T', 'Y', 'YES', 'F', 'N', 'NO' (case insensitive) can now also be converted to boolean. Compatibility: 'T', 'Y', 'YES', 'F', 'N', 'NO' (case insensitive) can now also be converted to boolean.
This is allowed now: WHERE BOOLEAN_FIELD='T'=(ID>1) This is allowed now: WHERE BOOLEAN_FIELD='T'=(ID>1)
...@@ -905,7 +917,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -905,7 +917,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
To avoid doing a table scan when no rows are in the table at prepare time, and many rows at execution time. To avoid doing a table scan when no rows are in the table at prepare time, and many rows at execution time.
Using a row count offset of 1000. Using a row count offset of 1000.
<li> <li>
MERGE: new SQL command to insert or update a row. Sometimes this is called UPSERT for UPdate or INSERT. MERGE: new SQL command to insert or update a row. Sometimes this is called UPSERT for update or insert.
The grammar is a lot simpler than what Oracle supports. The grammar is a lot simpler than what Oracle supports.
<li> <li>
SCRIPT: now the CREATE INDEX statements are after the INSERT statements, to improve performance. SCRIPT: now the CREATE INDEX statements are after the INSERT statements, to improve performance.
...@@ -992,7 +1004,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -992,7 +1004,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 0.9 / 2006-04-23</h3><ul> <h3>Version 0.9 / 2006-04-23</h3><ul>
<li> <li>
Improved Hibernate Dialect for SQuirrel DB Copy. Improved Hibernate Dialect for SQuirreL DB Copy.
<li> <li>
Support for UPDATE TEST SET (column [,...])=(select | expr [,...]'). Support for UPDATE TEST SET (column [,...])=(select | expr [,...]').
For Compiere compatibility. For Compiere compatibility.
...@@ -1252,7 +1264,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1252,7 +1264,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox) <li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox)
<li>Document how to use H2 with PHP (generic database API) <li>Document how to use H2 with PHP (generic database API)
<li>Optimization: result set caching (like MySQL) <li>Optimization: result set caching (like MySQL)
<li>MVCC (Multi Version Cuncurrency Control) <li>MVCC (Multi Version Concurrency Control)
<li>Server side cursors <li>Server side cursors
<li>Row level locking <li>Row level locking
<li>System table: open sessions and locks of a database <li>System table: open sessions and locks of a database
...@@ -1302,12 +1314,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1302,12 +1314,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Implement, test, document XAConnection and so on <li>Implement, test, document XAConnection and so on
<li>Web site: meta keywords, description, get rid of frame set <li>Web site: meta keywords, description, get rid of frame set
<li>Pluggable data type (for compression, validation, conversion, encryption) <li>Pluggable data type (for compression, validation, conversion, encryption)
<li>CHECK: find out what makes CHECK=TRUE slow, then: fast, nocheck, slow <li>CHECK: find out what makes CHECK=TRUE slow, then: fast, no check, slow
<li>Improve recovery: improve code for log recovery problems (less try/catch) <li>Improve recovery: improve code for log recovery problems (less try/catch)
<li>Log linear hash index changes, fast open / close <li>Log linear hash index changes, fast open / close
<li>Index usage for (ID, NAME)=(1, 'Hi'); document <li>Index usage for (ID, NAME)=(1, 'Hi'); document
<li>Faster hash function for strings, byte arrays, bigdecimal <li>Faster hash function for strings, byte arrays, big decimal
<li>Suggestion: include jetty as Servlet Container (not AMP but JHJ) <li>Suggestion: include jetty as Servlet Container (like LAMP)
<li>Trace shipping to server <li>Trace shipping to server
<li>Performance / server mode: delay prepare? use UDP? <li>Performance / server mode: delay prepare? use UDP?
<li>Version check: javascript in the docs / web console and maybe in the library <li>Version check: javascript in the docs / web console and maybe in the library
...@@ -1338,7 +1350,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1338,7 +1350,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Maybe include JTidy. Check license <li>Maybe include JTidy. Check license
<li>Server: client ping from time to time (to avoid timeout - is timeout a problem?) <li>Server: client ping from time to time (to avoid timeout - is timeout a problem?)
<li>Column level privileges <li>Column level privileges
<li>Copy database: Tool with config GUI and batch mode, extendable (example: compare) <li>Copy database: Tool with config GUI and batch mode, extensible (example: compare)
<li>Document shrinking jar file using http://proguard.sourceforge.net/ <li>Document shrinking jar file using http://proguard.sourceforge.net/
<li>Document, implement tool for long running transactions using user defined compensation statements <li>Document, implement tool for long running transactions using user defined compensation statements
<li>Support SET TABLE DUAL READONLY; <li>Support SET TABLE DUAL READONLY;
...@@ -1386,7 +1398,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1386,7 +1398,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Clustering: recovery needs to becomes fully automatic. <li>Clustering: recovery needs to becomes fully automatic.
<li>Date: default date is '1970-01-01' (is it 1900-01-01 in the standard / other databases?) <li>Date: default date is '1970-01-01' (is it 1900-01-01 in the standard / other databases?)
<li>Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID); <li>Test and document UPDATE TEST SET (ID, NAME) = (SELECT ID*10, NAME || '!' FROM TEST T WHERE T.ID=TEST.ID);
<li>Support home directory as ~ in database URL (jdbc:h2:file:~/.mydir/myDB) <li>Support home directory as ~ in database URL (jdbc:h2:file:~/.dir/db)
<li>Document EXISTS and so on, provide more samples. <li>Document EXISTS and so on, provide more samples.
<li>Modular build (multiple independent jars). <li>Modular build (multiple independent jars).
<li>Better space re-use in the files after deleting data (shrink the files) <li>Better space re-use in the files after deleting data (shrink the files)
...@@ -1420,7 +1432,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1420,7 +1432,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Clustering: When a database is back alive, automatically synchronize with the master <li>Clustering: When a database is back alive, automatically synchronize with the master
<li>Standalone tool to get relevant system properties and add it to the trace output. <li>Standalone tool to get relevant system properties and add it to the trace output.
<li>Support mixed clustering mode (one embedded, the other server mode) <li>Support mixed clustering mode (one embedded, the other server mode)
<li>Support 'call rpcname($1=somevalue)' (PostgreSQL, Oracle) <li>Support 'call proc($1=value)' (PostgreSQL, Oracle)
<li>HSQLDB compatibility: "INSERT INTO TEST(name) VALUES(?); SELECT IDENTITY()" <li>HSQLDB compatibility: "INSERT INTO TEST(name) VALUES(?); SELECT IDENTITY()"
<li>Shutdown lock (shutdown can only start if there are no logins pending, and logins are delayed until shutdown ends) <li>Shutdown lock (shutdown can only start if there are no logins pending, and logins are delayed until shutdown ends)
<li>Automatically delete the index file if opening it fails <li>Automatically delete the index file if opening it fails
...@@ -1454,14 +1466,14 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1454,14 +1466,14 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Backup tool should work with other databases as well <li>Backup tool should work with other databases as well
<li>Console: -ifExists doesn't work for the console. Add a flag to disable other dbs <li>Console: -ifExists doesn't work for the console. Add a flag to disable other dbs
<li>Maybe use Fowler Noll Vo hash function <li>Maybe use Fowler Noll Vo hash function
<li>Improved full text search (supports LOBs, readers / tokenizers / filters). <li>Improved full text search (supports LOBs, reader / tokenizer / filter).
<li>Performance: Update in-place <li>Performance: Update in-place
<li>Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess) <li>Check if 'FSUTIL behavior set disablelastaccess 1' improves the performance (fsutil behavior query disablelastaccess)
<li>Remove finally() (almost) everywhere <li>Remove finally() (almost) everywhere
<li>Java static code analysis: http://pmd.sourceforge.net/ <li>Java static code analysis: http://pmd.sourceforge.net/
<li>Java static code analysis: http://www.eclipse.org/tptp/ <li>Java static code analysis: http://www.eclipse.org/tptp/
<li>Java static code analysis: http://checkstyle.sourceforge.net/ <li>Java static code analysis: http://checkstyle.sourceforge.net/
<li>Compatiblity for CREATE SCHEMA AUTHORIZATION <li>Compatibility for CREATE SCHEMA AUTHORIZATION
<li>Implement Clob / Blob truncate and the remaining functionality <li>Implement Clob / Blob truncate and the remaining functionality
<li>Maybe close LOBs after closing connection <li>Maybe close LOBs after closing connection
<li>Tree join functionality <li>Tree join functionality
...@@ -1507,9 +1519,18 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -1507,9 +1519,18 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>User defined aggregate functions <li>User defined aggregate functions
<li>System property for base directory (h2.baseDir) in embedded mode <li>System property for base directory (h2.baseDir) in embedded mode
<li>Feature matrix like here: http://www.inetsoftware.de/products/jdbc/mssql/features/default.asp. <li>Feature matrix like here: http://www.inetsoftware.de/products/jdbc/mssql/features/default.asp.
<li>Updatable resultset on table without primary key or unique index <li>Updatable result set on table without primary key or unique index
<li>Use LinkedList instead of ArrayList where applicable <li>Use LinkedList instead of ArrayList where applicable
<li>Optimization: (A=B AND B=C) > (A=B AND B=C AND A=C) <li>Optimization: (A=B AND B=C) > (A=B AND B=C AND A=C)
<li>Support % operator (modulo)
<li>Large subqueries: close them when the main query is closed, not earlier (so result can be reused)
<li>Support 1+'2'=3, '1'+'2'='12' (MS SQL Server compatibility)
<li>Support nested transactions
<li>Add a benchmark for big databases, and one for many users
<li>Compression in the result set (repeating values in the same column)
<li>Improve command line consistency (+/- options, or true false options)
<li>Allow to use the catalog name in statements: [[catalog.]schema.]object
<li>Support curtimestamp (like curtime, curdate)
</ul> </ul>
<h3>Not Planned</h3> <h3>Not Planned</h3>
......
...@@ -137,7 +137,7 @@ Welcome to H2, the free SQL database. The main feature of H2 are: ...@@ -137,7 +137,7 @@ Welcome to H2, the free SQL database. The main feature of H2 are:
server/web/res/_text_*.properties). Or click on the PayPal button below to<br> server/web/res/_text_*.properties). Or click on the PayPal button below to<br>
donate money. You will be listed as a supporter: donate money. You will be listed as a supporter:
</p> </p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick"> <input type="hidden" name="cmd" value="_s-xclick">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit" alt="Zahlen Sie mit PayPal - schnell, kostenlos und sicher!"> <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit" alt="Zahlen Sie mit PayPal - schnell, kostenlos und sicher!">
<img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1"> <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
......
...@@ -62,31 +62,6 @@ In most cases H2 is a lot faster than all other ...@@ -62,31 +62,6 @@ In most cases H2 is a lot faster than all other
<tr><td>Statement per Second</td><td>#</td><td>9761</td><td>4546</td><td>1975</td><td>5259</td><td>7823</td></tr> <tr><td>Statement per Second</td><td>#</td><td>9761</td><td>4546</td><td>1975</td><td>5259</td><td>7823</td></tr>
</table> </table>
<h3>PolePosition Benchmark</h3>
<table border="1" class="bar">
<tr><th>Test Case</th><th>Unit</th><th>H2</th><th>HSQLDB</th><th>MySQL</th></tr>
<tr><td>Melbourne write</td><td>ms</td><td>369</td><td>249</td><td>2022</td></tr>
<tr><td>Melbourne read</td><td>ms</td><td>47</td><td>49</td><td>93</td></tr>
<tr><td>Melbourne read_hot</td><td>ms</td><td>24</td><td>43</td><td>95</td></tr>
<tr><td>Melbourne delete</td><td>ms</td><td>147</td><td>133</td><td>176</td></tr>
<tr><td>Sepang write</td><td>ms</td><td>965</td><td>1201</td><td>3213</td></tr>
<tr><td>Sepang read</td><td>ms</td><td>765</td><td>948</td><td>3455</td></tr>
<tr><td>Sepang read_hot</td><td>ms</td><td>789</td><td>859</td><td>3563</td></tr>
<tr><td>Sepang delete</td><td>ms</td><td>1384</td><td>1596</td><td>6214</td></tr>
<tr><td>Bahrain write</td><td>ms</td><td>1186</td><td>1387</td><td>6904</td></tr>
<tr><td>Bahrain query_indexed_string</td><td>ms</td><td>336</td><td>170</td><td>693</td></tr>
<tr><td>Bahrain query_string</td><td>ms</td><td>18064</td><td>39703</td><td>41243</td></tr>
<tr><td>Bahrain query_indexed_int</td><td>ms</td><td>104</td><td>134</td><td>678</td></tr>
<tr><td>Bahrain update</td><td>ms</td><td>191</td><td>87</td><td>159</td></tr>
<tr><td>Bahrain delete</td><td>ms</td><td>1215</td><td>729</td><td>6812</td></tr>
<tr><td>Imola retrieve</td><td>ms</td><td>198</td><td>194</td><td>4036</td></tr>
<tr><td>Barcelona write</td><td>ms</td><td>413</td><td>832</td><td>3191</td></tr>
<tr><td>Barcelona read</td><td>ms</td><td>119</td><td>160</td><td>1177</td></tr>
<tr><td>Barcelona query</td><td>ms</td><td>20</td><td>5169</td><td>101</td></tr>
<tr><td>Barcelona delete</td><td>ms</td><td>388</td><td>319</td><td>3287</td></tr>
<tr><td>Total</td><td>ms</td><td>26724</td><td>53962</td><td>87112</td></tr>
</table>
<h3>Benchmark Results and Comments</h3> <h3>Benchmark Results and Comments</h3>
<h4>H2</h4> <h4>H2</h4>
...@@ -218,6 +193,35 @@ and for each step a new connection is opened and then closed. ...@@ -218,6 +193,35 @@ and for each step a new connection is opened and then closed.
That means the Open/Close time listed is for opening a connection That means the Open/Close time listed is for opening a connection
if the database is already in use. if the database is already in use.
<h3>PolePosition Benchmark</h3>
<p>
The PolePosition is an open source benchmark. The algorithms are all quite simple.
It was developed / sponsored by db4o.
</p>
<table border="1" class="bar">
<tr><th>Test Case</th><th>Unit</th><th>H2</th><th>HSQLDB</th><th>MySQL</th></tr>
<tr><td>Melbourne write</td><td>ms</td><td>369</td><td>249</td><td>2022</td></tr>
<tr><td>Melbourne read</td><td>ms</td><td>47</td><td>49</td><td>93</td></tr>
<tr><td>Melbourne read_hot</td><td>ms</td><td>24</td><td>43</td><td>95</td></tr>
<tr><td>Melbourne delete</td><td>ms</td><td>147</td><td>133</td><td>176</td></tr>
<tr><td>Sepang write</td><td>ms</td><td>965</td><td>1201</td><td>3213</td></tr>
<tr><td>Sepang read</td><td>ms</td><td>765</td><td>948</td><td>3455</td></tr>
<tr><td>Sepang read_hot</td><td>ms</td><td>789</td><td>859</td><td>3563</td></tr>
<tr><td>Sepang delete</td><td>ms</td><td>1384</td><td>1596</td><td>6214</td></tr>
<tr><td>Bahrain write</td><td>ms</td><td>1186</td><td>1387</td><td>6904</td></tr>
<tr><td>Bahrain query_indexed_string</td><td>ms</td><td>336</td><td>170</td><td>693</td></tr>
<tr><td>Bahrain query_string</td><td>ms</td><td>18064</td><td>39703</td><td>41243</td></tr>
<tr><td>Bahrain query_indexed_int</td><td>ms</td><td>104</td><td>134</td><td>678</td></tr>
<tr><td>Bahrain update</td><td>ms</td><td>191</td><td>87</td><td>159</td></tr>
<tr><td>Bahrain delete</td><td>ms</td><td>1215</td><td>729</td><td>6812</td></tr>
<tr><td>Imola retrieve</td><td>ms</td><td>198</td><td>194</td><td>4036</td></tr>
<tr><td>Barcelona write</td><td>ms</td><td>413</td><td>832</td><td>3191</td></tr>
<tr><td>Barcelona read</td><td>ms</td><td>119</td><td>160</td><td>1177</td></tr>
<tr><td>Barcelona query</td><td>ms</td><td>20</td><td>5169</td><td>101</td></tr>
<tr><td>Barcelona delete</td><td>ms</td><td>388</td><td>319</td><td>3287</td></tr>
<tr><td>Total</td><td>ms</td><td>26724</td><td>53962</td><td>87112</td></tr>
</table>
<br><a name="application_profiling"></a> <br><a name="application_profiling"></a>
<h2>Application Profiling</h2> <h2>Application Profiling</h2>
......
...@@ -62,21 +62,21 @@ function listWords(value, open) { ...@@ -62,21 +62,21 @@ function listWords(value, open) {
word = wordRef.split("=")[0]; word = wordRef.split("=")[0];
var tr = table.insertRow(x++); var tr = table.insertRow(x++);
var td = document.createElement('td'); var td = document.createElement('td');
var tdc = document.createAttribute('class'); var tdClass = document.createAttribute('class');
tdc.nodeValue = 'searchKeyword'; tdClass.nodeValue = 'searchKeyword';
td.setAttributeNode(tdc); td.setAttributeNode(tdClass);
var ah = document.createElement('a'); var ah = document.createElement('a');
var hre = document.createAttribute('href'); var href = document.createAttribute('href');
hre.nodeValue = 'javascript:set("' + word + '");'; href.nodeValue = 'javascript:set("' + word + '");';
var link = document.createTextNode(word); var link = document.createTextNode(word);
ah.setAttributeNode(hre); ah.setAttributeNode(href);
ah.appendChild(link); ah.appendChild(link);
td.appendChild(ah); td.appendChild(ah);
tr.appendChild(td); tr.appendChild(td);
pis = wordRef.split("=")[1].split(","); piList = wordRef.split("=")[1].split(",");
if(count<20 || open==word) { if(count<20 || open==word) {
x = addReferences(x, pis, word); x = addReferences(x, piList, word);
} }
} }
} }
...@@ -129,10 +129,10 @@ function listAnd(keywords) { ...@@ -129,10 +129,10 @@ function listAnd(keywords) {
for(var j=0; j<words.length; j++) { for(var j=0; j<words.length; j++) {
var wordRef = words[j]; var wordRef = words[j];
if(wordRef.toLowerCase().indexOf(value)==0) { if(wordRef.toLowerCase().indexOf(value)==0) {
pis = wordRef.split("=")[1].split(","); piList = wordRef.split("=")[1].split(",");
var w=1; var w=1;
for(var k=0; k<pis.length; k++) { for(var k=0; k<piList.length; k++) {
var pi = pis[k]; var pi = piList[k];
if(pi.charAt(0) == 't') { if(pi.charAt(0) == 't') {
pi = pi.substring(1); pi = pi.substring(1);
w=10000; w=10000;
...@@ -155,36 +155,36 @@ function listAnd(keywords) { ...@@ -155,36 +155,36 @@ function listAnd(keywords) {
} }
var x = 0; var x = 0;
var table = document.getElementById('result'); var table = document.getElementById('result');
var pis = new Array(); var piList = new Array();
var piw = new Array(); var piWeight = new Array();
for(var i=0; i<pages.length; i++) { for(var i=0; i<pages.length; i++) {
if(count[i] >= keywords.length) { if(count[i] >= keywords.length) {
pis[x] = '' + i; piList[x] = '' + i;
piw[x] = weight[i]; piWeight[x] = weight[i];
x++; x++;
} }
} }
// sort // sort
for (var i = 1, j; i < x; i++) { for (var i = 1, j; i < x; i++) {
var tw = piw[i]; var tw = piWeight[i];
var ti = pis[i]; var ti = piList[i];
for (j = i - 1; j >= 0 && (piw[j] < tw); j--) { for (j = i - 1; j >= 0 && (piWeight[j] < tw); j--) {
piw[j + 1] = piw[j]; piWeight[j + 1] = piWeight[j];
pis[j + 1] = pis[j]; piList[j + 1] = piList[j];
} }
piw[j + 1] = tw; piWeight[j + 1] = tw;
pis[j + 1] = ti; piList[j + 1] = ti;
} }
addReferences(0, pis, keywords); addReferences(0, piList, keywords);
if(pis.length == 0) { if(piList.length == 0) {
noResults(table); noResults(table);
} }
} }
function addReferences(x, pis, word) { function addReferences(x, piList, word) {
var table = document.getElementById('result'); var table = document.getElementById('result');
for(var j=0; j<pis.length; j++) { for(var j=0; j<piList.length; j++) {
var pi = pis[j]; var pi = piList[j];
if(pi.charAt(0) == 't') { if(pi.charAt(0) == 't') {
pi = pi.substring(1); pi = pi.substring(1);
} else if(pi.charAt(0) == 'h') { } else if(pi.charAt(0) == 'h') {
...@@ -194,18 +194,18 @@ function addReferences(x, pis, word) { ...@@ -194,18 +194,18 @@ function addReferences(x, pis, word) {
} }
var tr = table.insertRow(x++); var tr = table.insertRow(x++);
var td = document.createElement('td'); var td = document.createElement('td');
var tdc = document.createAttribute('class'); var tdClass = document.createAttribute('class');
tdc.nodeValue = 'searchLink'; tdClass.nodeValue = 'searchLink';
td.setAttributeNode(tdc); td.setAttributeNode(tdClass);
var ah = document.createElement('a'); var ah = document.createElement('a');
var hre = document.createAttribute('href'); var href = document.createAttribute('href');
var thisLink = 'javascript:go(' + pi + ', "' + word + '")'; var thisLink = 'javascript:go(' + pi + ', "' + word + '")';
if(firstLink==null) { if(firstLink==null) {
firstLink = pi; firstLink = pi;
firstLinkWord = word; firstLinkWord = word;
} }
hre.nodeValue = thisLink; href.nodeValue = thisLink;
ah.setAttributeNode(hre); ah.setAttributeNode(href);
var page = pages[pi]; var page = pages[pi];
var link = document.createTextNode(page.title); var link = document.createTextNode(page.title);
ah.appendChild(link); ah.appendChild(link);
...@@ -240,9 +240,9 @@ function replaceOtherChars(s) { ...@@ -240,9 +240,9 @@ function replaceOtherChars(s) {
function noResults(table) { function noResults(table) {
var tr = table.insertRow(0); var tr = table.insertRow(0);
var td = document.createElement('td'); var td = document.createElement('td');
var tdc = document.createAttribute('class'); var tdClass = document.createAttribute('class');
tdc.nodeValue = 'searchKeyword'; tdClass.nodeValue = 'searchKeyword';
td.setAttributeNode(tdc); td.setAttributeNode(tdClass);
var text = document.createTextNode('No results found'); var text = document.createTextNode('No results found');
td.appendChild(text); td.appendChild(text);
tr.appendChild(td); tr.appendChild(td);
......
...@@ -27,7 +27,7 @@ Tutorial ...@@ -27,7 +27,7 @@ Tutorial
CSV (Comma Separated Values) Support</a><br> CSV (Comma Separated Values) Support</a><br>
<a href="#upgrade_backup_restore"> <a href="#upgrade_backup_restore">
Upgrade, Backup, and Restore</a><br> Upgrade, Backup, and Restore</a><br>
<a href="#openoffice"> <a href="#open_office">
Using OpenOffice Base</a><br> Using OpenOffice Base</a><br>
<br><a name="tutorial_starting_h2_console"></a> <br><a name="tutorial_starting_h2_console"></a>
...@@ -384,8 +384,8 @@ SimpleResultSet rs = new SimpleResultSet(); ...@@ -384,8 +384,8 @@ SimpleResultSet rs = new SimpleResultSet();
rs.addColumn("NAME", Types.VARCHAR, 255, 0); rs.addColumn("NAME", Types.VARCHAR, 255, 0);
rs.addColumn("EMAIL", Types.VARCHAR, 255, 0); rs.addColumn("EMAIL", Types.VARCHAR, 255, 0);
rs.addColumn("PHONE", Types.VARCHAR, 255, 0); rs.addColumn("PHONE", Types.VARCHAR, 255, 0);
rs.addRow(new String[]{"Bob Meier", "bob.meier@abcde.fgh", "+41123456789"}); rs.addRow(new String[]{"Bob Meier", "bob.meier@abcde.abc", "+41123456789"});
rs.addRow(new String[]{"John Jones", "johnjones@abcde.fgh", "+41976543210"}); rs.addRow(new String[]{"John Jones", "john.jones@abcde.abc", "+41976543210"});
Csv.write("test.csv", rs, null); Csv.write("test.csv", rs, null);
</pre> </pre>
...@@ -438,7 +438,7 @@ SQL script files may contain references to other script files, in the form of ...@@ -438,7 +438,7 @@ SQL script files may contain references to other script files, in the form of
RUNSCRIPT commands. However, when using the server mode, the references script files RUNSCRIPT commands. However, when using the server mode, the references script files
need to be available on the server side. need to be available on the server side.
<br><a name="openoffice"></a> <br><a name="open_office"></a>
<h2>Using OpenOffice Base</h2> <h2>Using OpenOffice Base</h2>
OpenOffice.org Base supports database access over the JDBC API. To connect to a H2 database OpenOffice.org Base supports database access over the JDBC API. To connect to a H2 database
using OpenOffice Base, you first need to add the JDBC driver to OpenOffice. using OpenOffice Base, you first need to add the JDBC driver to OpenOffice.
......
...@@ -1705,7 +1705,9 @@ public class Parser { ...@@ -1705,7 +1705,9 @@ public class Parser {
Sequence sequence = database.getSchema(schemaName).findSequence(objectName); Sequence sequence = database.getSchema(schemaName).findSequence(objectName);
if(sequence != null) { if(sequence != null) {
Function function = Function.getFunction(database, "CURRVAL"); Function function = Function.getFunction(database, "CURRVAL");
function.setParameter(0, ValueExpression.get(ValueString.get(objectName))); function.setParameter(0, ValueExpression.get(ValueString.get(schemaName)));
function.setParameter(1, ValueExpression.get(ValueString.get(objectName)));
function.doneWithParameters();
return function; return function;
} }
} }
...@@ -1931,6 +1933,7 @@ public class Parser { ...@@ -1931,6 +1933,7 @@ public class Parser {
function.setParameter(0, when); function.setParameter(0, when);
function.setParameter(1, then); function.setParameter(1, then);
function.setParameter(2, elsePart); function.setParameter(2, elsePart);
function.doneWithParameters();
return function; return function;
} }
...@@ -3587,12 +3590,12 @@ public class Parser { ...@@ -3587,12 +3590,12 @@ public class Parser {
command.setStartWith(start); command.setStartWith(start);
return command; return command;
} else if(readIf("SELECTIVITY")) { } else if(readIf("SELECTIVITY")) {
int sel = getPositiveInt(); int selectivity = getPositiveInt();
AlterTableAlterColumn command = new AlterTableAlterColumn(session, tableSchema); AlterTableAlterColumn command = new AlterTableAlterColumn(session, tableSchema);
command.setTable(table); command.setTable(table);
command.setType(AlterTableAlterColumn.SELECTIVITY); command.setType(AlterTableAlterColumn.SELECTIVITY);
command.setOldColumn(column); command.setOldColumn(column);
command.setStartWith(sel); command.setStartWith(selectivity);
return command; return command;
} else { } else {
Column newColumn = parseColumnForTable(columnName); Column newColumn = parseColumnForTable(columnName);
......
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.dml; package org.h2.command.dml;
import java.io.FileInputStream; import java.io.FileInputStream;
...@@ -50,38 +54,32 @@ public class Backup extends Prepared { ...@@ -50,38 +54,32 @@ public class Backup extends Prepared {
name = FileUtils.getFileName(name); name = FileUtils.getFileName(name);
FileOutputStream zip = new FileOutputStream(fileName); FileOutputStream zip = new FileOutputStream(fileName);
ZipOutputStream out = new ZipOutputStream(zip); ZipOutputStream out = new ZipOutputStream(zip);
out.putNextEntry(new ZipEntry(name + Constants.SUFFIX_DATA_FILE));
DiskFile file = db.getDataFile();
LogSystem log = db.getLog(); LogSystem log = db.getLog();
try { try {
log.flush();
log.updateKeepFiles(1); log.updateKeepFiles(1);
int pos = -1; String fn = db.getName() + Constants.SUFFIX_DATA_FILE;
int max = file.getReadCount(); backupDiskFile(out, fn, db.getDataFile());
while(true) { fn = db.getName() + Constants.SUFFIX_INDEX_FILE;
pos = file.readDirect(pos, out); backupDiskFile(out, fn, db.getIndexFile());
if(pos < 0) {
break;
}
db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, name, pos, max);
}
out.closeEntry();
ObjectArray list = log.getActiveLogFiles(); ObjectArray list = log.getActiveLogFiles();
max = list.size(); int max = list.size();
for(int i=0; i<list.size(); i++) { // synchronize on the database, to avoid concurrent temp file creation / deletion / backup
LogFile lf = (LogFile) list.get(i); synchronized(db.getLobSyncObject()) {
String fn = lf.getFileName(); for(int i=0; i<list.size(); i++) {
out.putNextEntry(new ZipEntry(FileUtils.getFileName(fn))); LogFile lf = (LogFile) list.get(i);
FileInputStream in = new FileInputStream(fn); fn = lf.getFileName();
IOUtils.copyAndCloseInput(in, out); backupFile(out, fn);
out.closeEntry(); db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, name, i, max);
db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, name, i, max); }
} ArrayList fileList = FileBase.getDatabaseFiles(db.getDatabasePath(), name, true);
int todoLockDatabaseSomehow; for(int i=0; i<fileList.size(); i++) {
ArrayList fileList = FileBase.getDatabaseFiles(db.getDatabasePath(), name, true); fn = (String) fileList.get(i);
for(int i=0; i<fileList.size(); i++) { if(fn.endsWith(Constants.SUFFIX_HASH_FILE) || fn.endsWith(Constants.SUFFIX_LOB_FILE)) {
String fn = (String) fileList.get(i); backupFile(out, fn);
}
}
} }
int todoCopyLobFiles;
out.close(); out.close();
zip.close(); zip.close();
} finally { } finally {
...@@ -91,6 +89,29 @@ public class Backup extends Prepared { ...@@ -91,6 +89,29 @@ public class Backup extends Prepared {
throw Message.convert(e); throw Message.convert(e);
} }
} }
private void backupDiskFile(ZipOutputStream out, String fileName, DiskFile file) throws SQLException, IOException {
Database db = session.getDatabase();
fileName = FileUtils.getFileName(fileName);
out.putNextEntry(new ZipEntry(fileName));
int pos = -1;
int max = file.getReadCount();
while(true) {
pos = file.readDirect(pos, out);
if(pos < 0) {
break;
}
db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, fileName, pos, max);
}
out.closeEntry();
}
private void backupFile(ZipOutputStream out, String fn) throws SQLException, IOException {
out.putNextEntry(new ZipEntry(FileUtils.getFileName(fn)));
FileInputStream in = new FileInputStream(fn);
IOUtils.copyAndCloseInput(in, out);
out.closeEntry();
}
public boolean isTransactional() { public boolean isTransactional() {
return true; return true;
......
...@@ -83,8 +83,10 @@ public abstract class Query extends Prepared { ...@@ -83,8 +83,10 @@ public abstract class Query extends Prepared {
if(lastResult != null && limit == lastLimit) { if(lastResult != null && limit == lastLimit) {
if(sameResultAsLast(session, params, lastParameters, lastEvaluated)) { if(sameResultAsLast(session, params, lastParameters, lastEvaluated)) {
lastResult = lastResult.createShallowCopy(session); lastResult = lastResult.createShallowCopy(session);
lastResult.reset(); if(lastResult != null) {
return lastResult; lastResult.reset();
return lastResult;
}
} }
} }
lastParameters = params; lastParameters = params;
......
...@@ -201,4 +201,8 @@ public class ScriptBase extends Prepared implements DataHandler { ...@@ -201,4 +201,8 @@ public class ScriptBase extends Prepared implements DataHandler {
this.compressionAlgorithm = algorithm; this.compressionAlgorithm = algorithm;
} }
public Object getLobSyncObject() {
return this;
}
} }
...@@ -4,19 +4,12 @@ ...@@ -4,19 +4,12 @@
*/ */
package org.h2.command.dml; package org.h2.command.dml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.store.DiskFile;
/** /**
...@@ -124,32 +117,6 @@ public class TransactionCommand extends Prepared { ...@@ -124,32 +117,6 @@ public class TransactionCommand extends Prepared {
return 0; return 0;
} }
private void backupTo(String fileName) throws SQLException {
int todoMoveToOwnCommand;
try {
FileOutputStream fileOut = new FileOutputStream("test.zip");
ZipOutputStream out = new ZipOutputStream(fileOut);
out.putNextEntry(new ZipEntry("test.data.db"));
DiskFile file = session.getDatabase().getDataFile();
try {
session.getDatabase().getLog().updateKeepFiles(1);
int pos = -1;
while(true) {
pos = file.readDirect(pos, out);
if(pos < 0) {
break;
}
}
out.close();
fileOut.close();
} finally {
session.getDatabase().getLog().updateKeepFiles(-1);
}
} catch(IOException e) {
throw Message.convert(e);
}
}
public boolean isTransactional() { public boolean isTransactional() {
return true; return true;
} }
......
...@@ -49,11 +49,10 @@ public class CompressLZF implements Compressor { ...@@ -49,11 +49,10 @@ public class CompressLZF implements Compressor {
return Compressor.LZF; return Compressor.LZF;
} }
static final int HLOG = 14; private static final int HASH_SIZE = (1 << 14);
static final int HASH_SIZE = (1 << 14); private static final int MAX_LITERAL = (1 << 5);
static final int MAX_LITERAL = (1 << 5); private static final int MAX_OFF = (1 << 13);
static final int MAX_OFF = (1 << 13); private static final int MAX_REF = ((1 << 8) + (1 << 3));
static final int MAX_REF = ((1 << 8) + (1 << 3));
int first(byte[] in, int inPos) { int first(byte[] in, int inPos) {
return (in[inPos] << 8) + (in[inPos + 1] & 255); return (in[inPos] << 8) + (in[inPos + 1] & 255);
...@@ -79,11 +78,11 @@ public class CompressLZF implements Compressor { ...@@ -79,11 +78,11 @@ public class CompressLZF implements Compressor {
System.arraycopy(empty, 0, hashTab, 0, HASH_SIZE); System.arraycopy(empty, 0, hashTab, 0, HASH_SIZE);
} }
int literals = 0; int literals = 0;
int hval = first(in, inPos); int hash = first(in, inPos);
while (true) { while (true) {
if (inPos < inLen - 4) { if (inPos < inLen - 4) {
hval = next(hval, in, inPos); hash = next(hash, in, inPos);
int off = hash(hval); int off = hash(hash);
int ref = hashTab[off]; int ref = hashTab[off];
hashTab[off] = inPos; hashTab[off] = inPos;
off = inPos - ref - 1; off = inPos - ref - 1;
...@@ -110,11 +109,11 @@ public class CompressLZF implements Compressor { ...@@ -110,11 +109,11 @@ public class CompressLZF implements Compressor {
} }
out[outPos++] = (byte) off; out[outPos++] = (byte) off;
inPos += len; inPos += len;
hval = first(in, inPos); hash = first(in, inPos);
hval = next(hval, in, inPos); hash = next(hash, in, inPos);
hashTab[hash(hval)] = inPos++; hashTab[hash(hash)] = inPos++;
hval = next(hval, in, inPos); hash = next(hash, in, inPos);
hashTab[hash(hval)] = inPos++; hashTab[hash(hash)] = inPos++;
continue; continue;
} }
} else if (inPos == inLen) { } else if (inPos == inLen) {
......
...@@ -17,7 +17,11 @@ package org.h2.engine; ...@@ -17,7 +17,11 @@ package org.h2.engine;
* - Compiling with JDK 1.3, 1.4, 1.5 and 1.6 * - Compiling with JDK 1.3, 1.4, 1.5 and 1.6
* *
* set path=C:\jdk1.3.1_19\bin;%PATH% * set path=C:\jdk1.3.1_19\bin;%PATH%
* set JAVA_HOME=C:\jdk1.3.1_19\bin * set JAVA_HOME=C:\jdk1.3.1_19
* ant codeswitch_jdk13
* ant compile
* set path=C:\Programme\Java\jdk1.6.0\bin;%PATH%
* set JAVA_HOME=C:\Programme\Java\jdk1.6.0
* ant codeswitch_jdk16 * ant codeswitch_jdk16
* ant compile * ant compile
* *
...@@ -38,7 +42,7 @@ package org.h2.engine; ...@@ -38,7 +42,7 @@ package org.h2.engine;
* - Change version(s) in performance.html; use latest versions of other databases * - Change version(s) in performance.html; use latest versions of other databases
* - Run 'ant benchmark' (with JDK 1.4 currently) * - Run 'ant benchmark' (with JDK 1.4 currently)
* - Copy the benchmark results and update the performance page and diagram * - Copy the benchmark results and update the performance page and diagram
* (remove rows 2*open/close, 2*executed statement) * (remove 2*executed statement)
* *
* - Documentation: if there are new files, add them to MergeDocs * - Documentation: if there are new files, add them to MergeDocs
* - Documentation: check if all javadoc files are in the index * - Documentation: check if all javadoc files are in the index
...@@ -69,8 +73,8 @@ package org.h2.engine; ...@@ -69,8 +73,8 @@ package org.h2.engine;
*/ */
public class Constants { public class Constants {
public static final int BUILD_ID = 40; public static final int BUILD_ID = 41;
private static final String BUILD = "2007-01-17"; private static final String BUILD = "2007-01-30";
public static final int VERSION_MAJOR = 1; public static final int VERSION_MAJOR = 1;
public static final int VERSION_MINOR = 0; public static final int VERSION_MINOR = 0;
...@@ -118,7 +122,6 @@ public class Constants { ...@@ -118,7 +122,6 @@ public class Constants {
public static final String SUFFIX_TRACE_FILE = ".trace.db"; public static final String SUFFIX_TRACE_FILE = ".trace.db";
public static final String SUFFIX_LOB_FILE = ".lob.db"; public static final String SUFFIX_LOB_FILE = ".lob.db";
public static final String SUFFIX_TRACE_START_FILE = ".start"; public static final String SUFFIX_TRACE_START_FILE = ".start";
public static final String SUFFIX_SUMMARY_FILE = ".sum.db";
public static final String SUFFIX_LOBS_DIRECTORY = ".lobs.db"; public static final String SUFFIX_LOBS_DIRECTORY = ".lobs.db";
public static final String UTF8 = "UTF8"; public static final String UTF8 = "UTF8";
......
...@@ -133,6 +133,7 @@ public class Database implements DataHandler { ...@@ -133,6 +133,7 @@ public class Database implements DataHandler {
private boolean optimizeReuseResults = true; private boolean optimizeReuseResults = true;
private String cacheType; private String cacheType;
private boolean indexSummaryValid = true; private boolean indexSummaryValid = true;
private Object lobSyncObject = new Object();
public static void setInitialPowerOffCount(int count) { public static void setInitialPowerOffCount(int count) {
initialPowerOffCount = count; initialPowerOffCount = count;
...@@ -1483,4 +1484,8 @@ public class Database implements DataHandler { ...@@ -1483,4 +1484,8 @@ public class Database implements DataHandler {
return indexSummaryValid; return indexSummaryValid;
} }
public Object getLobSyncObject() {
return lobSyncObject;
}
} }
...@@ -153,7 +153,7 @@ public class FunctionAlias extends DbObject { ...@@ -153,7 +153,7 @@ public class FunctionAlias extends DbObject {
// need to set to default value otherwise the function can't be called at all // need to set to default value otherwise the function can't be called at all
o = DataType.getDefaultForPrimitiveType(paramClass); o = DataType.getDefaultForPrimitiveType(paramClass);
} else { } else {
// NULL value for a java primitive: return NULL // NULL for a java primitive: return NULL
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
} }
} }
......
...@@ -203,7 +203,7 @@ public class Session implements SessionInterface { ...@@ -203,7 +203,7 @@ public class Session implements SessionInterface {
Iterator it = unlinkSet.iterator(); Iterator it = unlinkSet.iterator();
while(it.hasNext()) { while(it.hasNext()) {
Value v = (Value) it.next(); Value v = (Value) it.next();
v.unlink(database); v.unlink();
} }
unlinkSet = null; unlinkSet = null;
} }
......
...@@ -53,6 +53,7 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -53,6 +53,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
private String databaseName; private String databaseName;
private String cipher; private String cipher;
private byte[] fileEncryptionKey; private byte[] fileEncryptionKey;
private Object lobSyncObject = new Object();
private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException, SQLException { private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException, SQLException {
int port = Constants.DEFAULT_SERVER_PORT; int port = Constants.DEFAULT_SERVER_PORT;
...@@ -91,12 +92,12 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -91,12 +92,12 @@ public class SessionRemote implements SessionInterface, DataHandler {
return trans; return trans;
} }
private void switchOffAutocommitIfCluster() throws SQLException { private void switchOffAutoCommitIfCluster() throws SQLException {
if(autoCommit && transferList.size() > 1) { if(autoCommit && transferList.size() > 1) {
if(switchOffAutoCommit == null) { if(switchOffAutoCommit == null) {
switchOffAutoCommit = prepareCommand("SET AUTOCOMMIT FALSE"); switchOffAutoCommit = prepareCommand("SET AUTOCOMMIT FALSE");
} }
// this will call setAutocommit(false) // this will call setAutoCommit(false)
switchOffAutoCommit.executeUpdate(); switchOffAutoCommit.executeUpdate();
// so we need to switch it on // so we need to switch it on
autoCommit = true; autoCommit = true;
...@@ -109,7 +110,7 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -109,7 +110,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
public void autoCommitIfCluster() throws SQLException { public void autoCommitIfCluster() throws SQLException {
if(autoCommit && transferList!= null && transferList.size() > 1) { if(autoCommit && transferList!= null && transferList.size() > 1) {
// server side autocommit is off because of race conditions // server side auto commit is off because of race conditions
// (update set id=1 where id=0, but update set id=2 where id=0 is faster) // (update set id=1 where id=0, but update set id=2 where id=0 is faster)
for(int i=0; i<transferList.size(); i++) { for(int i=0; i<transferList.size(); i++) {
Transfer transfer = (Transfer) transferList.get(i); Transfer transfer = (Transfer) transferList.get(i);
...@@ -217,7 +218,7 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -217,7 +218,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
if(switchOffCluster) { if(switchOffCluster) {
switchOffCluster(); switchOffCluster();
} }
switchOffAutocommitIfCluster(); switchOffAutoCommitIfCluster();
} }
private void switchOffCluster() throws SQLException { private void switchOffCluster() throws SQLException {
...@@ -379,4 +380,8 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -379,4 +380,8 @@ public class SessionRemote implements SessionInterface, DataHandler {
return this; return this;
} }
public Object getLobSyncObject() {
return lobSyncObject;
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论