提交 2ceb8a1f authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 275f182a
......@@ -139,6 +139,8 @@
<java classname="org.h2.tools.doc.LinkChecker" classpath="bin">
<arg line="-dir docs"/>
</java>
<java classname="org.h2.tools.doc.XMLChecker" classpath="bin">
</java>
</target>
<target name="gcj" depends="compileResources">
......
......@@ -12,41 +12,41 @@ Advanced Topics
<h1>Advanced Topics</h1>
<a href="#resultsets">
Result Sets</a><br />
Result Sets</a><br>
<a href="#large_objects">
Large Objects</a><br />
Large Objects</a><br>
<a href="#linked_tables">
Linked Tables</a><br />
Linked Tables</a><br>
<a href="#transaction_isolation">
Transaction Isolation</a><br />
Transaction Isolation</a><br>
<a href="#clustering">
Clustering / High Availability</a><br />
Clustering / High Availability</a><br>
<a href="#two_phase_commit">
Two Phase Commit</a><br />
Two Phase Commit</a><br>
<a href="#compatibility">
Compatibility</a><br />
Compatibility</a><br>
<a href="#windows_service">
Run as Windows Service</a><br />
Run as Windows Service</a><br>
<a href="#odbc_driver">
ODBC Driver</a><br />
ODBC Driver</a><br>
<a href="#acid">
ACID</a><br />
ACID</a><br>
<a href="#using_recover_tool">
Using the Recover Tool</a><br />
Using the Recover Tool</a><br>
<a href="#file_locking_protocols">
File Locking Protocols</a><br />
File Locking Protocols</a><br>
<a href="#sql_injection">
Protection against SQL Injection</a><br />
Protection against SQL Injection</a><br>
<a href="#security_protocols">
Security Protocols</a><br />
Security Protocols</a><br>
<a href="#uuid">
Universally Unique Identifiers (UUID)</a><br />
Universally Unique Identifiers (UUID)</a><br>
<a href="#system_properties">
Settings Read from System Properties</a><br />
Settings Read from System Properties</a><br>
<a href="#glossary_links">
Glossary and Links</a><br />
Glossary and Links</a><br>
<br /><a name="resultsets"></a>
<br><a name="resultsets"></a>
<h2>Result Sets</h2>
<h3>Limiting the Number of Rows</h3>
......@@ -62,7 +62,7 @@ For result set larger than 1000 rows, the result is buffered to disk. If ORDER B
the sorting is done using an external sort algorithm. In this case, each block of rows is sorted using
quick sort, then written to disk; when reading the data, the blocks are merged together.
<br /><a name="large_objects"></a>
<br><a name="large_objects"></a>
<h2>Large Objects</h2>
<h3>Storing and Reading Large Objects</h3>
......@@ -75,7 +75,7 @@ and to read a CLOB, use ResultSet.getCharacterStream.
If the client/server mode is used, the BLOB and CLOB data is fully read into memory when
accessed. In this case, the size of a BLOB or CLOB is limited by the memory.
<br /><a name="linked_tables"></a>
<br><a name="linked_tables"></a>
<h2>Linked Tables</h2>
This database supports linked tables, which means tables that don't exist in the current database but
......@@ -88,18 +88,18 @@ There is a restriction when inserting data to this table: When inserting or upda
NULL values 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.
<br /><a name="transaction_isolation"></a>
<br><a name="transaction_isolation"></a>
<h2>Transaction Isolation</h2>
This database supports the transaction isolation level 'serializable', in which dirty reads, non-repeatable
reads and phantom reads are prohibited.
<ul>
<li><b>Dirty Reads</b><br />
<li><b>Dirty Reads</b><br>
Means a connection can read uncommitted changes made by another connection.
<li><b>Non-Repeatable Reads</b><br />
<li><b>Non-Repeatable Reads</b><br>
A connection reads a row, another connection changes a row and commits,
and the first connection re-reads the same row and gets the new result.
<li><b>Phantom Reads</b><br />
<li><b>Phantom Reads</b><br>
A connection reads a set of rows using a condition, another connection
inserts a row that falls in this condition and commits, then the first connection
re-reads using the same condition and gets the new row.
......@@ -127,7 +127,7 @@ the other connection does not release the lock for some time, the unsuccessful
connection will get a lock timeout exception. The lock timeout can be set individually
for each connection.
<br /><a name="clustering"></a>
<br><a name="clustering"></a>
<h2>Clustering / High Availability</h2>
<p>
This database supports a simple clustering / high availability mechanism. The architecture is:
......@@ -203,7 +203,7 @@ CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should no
directly in modifying statements (for example INSERT, UPDATE, or MERGE). However, they can be used
in read-only statements and the result can then be used for modifying statements.
<br /><a name="two_phase_commit"></a>
<br><a name="two_phase_commit"></a>
<h2>Two Phase Commit</h2>
The two phase commit protocol is supported. 2-phase-commit works as follows:
<ul>
......@@ -222,7 +222,7 @@ The two phase commit protocol is supported. 2-phase-commit works as follows:
<li>The database needs to be closed and re-opened to apply the changes
</ul>
<br /><a name="compatibility"></a>
<br><a name="compatibility"></a>
<h2>Compatibility</h2>
This database is (up to a certain point) compatible to other databases such as HSQLDB, MySQL and PostgreSQL.
......@@ -234,17 +234,19 @@ For a query, this means the transaction is committed even before the application
Other database engines may commit the transaction in this case when the result set is closed.
<h3>Keywords / Reserved Words</h3>
<p>
There is a list of keywords that can't be used as identifiers (table names, column names and so on),
unless they are quoted (surrounded with double quotes). The list is currently:
<p>
</p><p>
CURRENT_TIMESTAMP, CURRENT_TIME, CURRENT_DATE, CROSS, DISTINCT, EXCEPT, EXISTS, FROM,
FOR, FALSE, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, MINUS, NATURAL, NOT, NULL,
ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, WHERE
<p>
</p><p>
Certain words of this list are keywords because they are functions that can be used without '()' for compatibility,
for example CURRENT_TIMESTAMP.
</p>
<br /><a name="windows_service"></a>
<br><a name="windows_service"></a>
<h2>Run as Windows Service</h2>
Using a native wrapper / adapter, Java applications can be run as a Windows Service.
There are various tools available to do that. The Java Service Wrapper from Tanuki Software, Inc.
......@@ -276,7 +278,7 @@ Please note that the batch file does not print an error message if the service i
To uninstall the service, double click on 5_uninstall_service.bat.
If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear.
<br /><a name="odbc_driver"></a>
<br><a name="odbc_driver"></a>
<h2>ODBC Driver</h2>
The ODBC driver of this database is currently not very stable and only tested superficially
with a few applications (OpenOffice 2.0, Microsoft Excel and Microsoft Access) and
......@@ -284,14 +286,15 @@ data types (INT and VARCHAR), and should not be used for production applications
Only a Windows version of the driver is available at this time.
<h3>ODBC Installation</h3>
<p>
Before the ODBC driver can be used, it needs to be installed. To do this,
double click on h2odbcSetup.exe. If you do this the first time, it will ask you to locate the
driver dll (h2odbc.dll). If you already installed it, the ODBC administration dialog will open
where you can create new or modify existing data sources.
When you create a new H2 ODBC data source, a dialog window will appear
and ask for the database settings:
<p>
<img src="odbcDataSource.png" alt="ODBC Configuration"/>
</p>
<img src="odbcDataSource.png" alt="ODBC Configuration">
<h3>Log Option</h3>
The driver is able to log operations to a file.
......@@ -319,7 +322,7 @@ Therefore the ODBC driver should not be used where security is important.
<h3>Uninstalling</h3>
To uninstall the ODBC driver, double click on h2odbcUninstall.exe. This will uninstall the driver.
<br /><a name="acid"></a>
<br><a name="acid"></a>
<h2>ACID</h2>
In the DBMS world, ACID stands for Atomicity, Consistency, Isolation, and Durability.
<ul>
......@@ -344,13 +347,15 @@ In many database, this rule is often relaxed to provide better performance,
by supporting other transaction isolation levels.
<h3>Durability</h3>
<p>
This database does not guarantee that all committed transactions survive a power failure.
If durability is required even in case of power failure, some sort of uninterruptible power supply (UPS) is required
(like using a laptop, or a battery pack). If durability is required even in case of hardware failure,
the clustering mode of this database should be used.
<p>
</p><p>
To achieve durability, it would be required to flush all file buffers (including system buffers) to hard disk for each commit.
In Java, there are two ways how this can be achieved:
</p>
<ul>
<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
......@@ -363,6 +368,7 @@ There is one related option, but it does not force changes to disk: RandomAccess
<li>rws: Every update to the file's content or metadata is written synchronously to the underlying storage device.
<li>rwd: Every update to the file's content is written synchronously to the underlying storage device.
</ul>
<p>
A simple power-off test using two computers (they communicate over the network, and one the power
is switched off on one computer) shows that the data is not always persisted to the hard drive,
even when calling FileDescriptor.sync() or FileChannel.force().
......@@ -370,7 +376,7 @@ The reason for this is that most hard drives do not obey the fsync() function.
For more information, see 'Your Hard Drive Lies to You' http://hardware.slashdot.org/article.pl?sid=05/05/13/0529252&amp;tid=198&amp;tid=128).
The test was made with this database, as well as with PostgreSQL, Derby, and HSQLDB.
None of those databases was able to guarantee complete transaction durability.
<p>
</p><p>
The test also shows that when calling FileDescriptor.sync() or FileChannel.force() after each file operation,
only around 30 file operations per second can be made. That means, the fastest possible Java database
that calls one of those functions can reach a maximum of around 30 committed
......@@ -378,13 +384,13 @@ transactions per second.
Without calling these functions, around 400000 file operations per second are possible
when using RandomAccessFile(..,"rw"), and around 2700 when using
RandomAccessFile(.., "rws"/"rwd").
<p>
</p><p>
That means that when using one of those functions, the performance goes down to at most
30 committed transactions per second, and even then there is no guarantee that transactions are durable.
These are the reasons that this database does not guarantee durability of transaction by default.
The database calls FileDescriptor.sync() when executing the SQL statement CHECKPOINT SYNC.
But by default, this database uses an asynchronous commit.
</p>
<h3>Running the Durability Test</h3>
To test the durability / non-durability of this and other databases, you can use the test application
in the package org.h2.test.poweroff. Two computers with network connection are required to run this test.
......@@ -399,7 +405,7 @@ run the application again. You will find out that in most cases, none of the dat
records that the listener computer knows about. For details, please consult the source code of the
listener and test application.
<br /><a name="using_recover_tool"></a>
<br><a name="using_recover_tool"></a>
<h2>Using the Recover Tool</h2>
The recover tool can be used to extract the contents of a data file, even if the database is corrupted.
At this time, it does not extract the content of the log file or large objects (CLOB or BLOB).
......@@ -412,12 +418,13 @@ This file contains raw insert statement (for the data) and data definition (DDL)
the schema of the database. This file cannot be executed directly, as the raw insert statements
don't have the correct table names, so the file needs to be pre-processed manually before executing.
<br /><a name="file_locking_protocols"></a>
<br><a name="file_locking_protocols"></a>
<h2>File Locking Protocols</h2>
<p>
Whenever a database is opened, a lock file is created to signal other processes
that the database is in use. If database is closed, or if the process that opened
the database terminates, this lock file is deleted.
<p>
</p><p>
In special cases (if the process did not terminate normally, for example because
there was a blackout), the lock file is not deleted by the process that created it.
That means the existence of the lock file is not a safe protocol for file locking.
......@@ -426,6 +433,7 @@ files. There are two methods (algorithms) implemented to provide both security
(that is, the same database files cannot be opened by two processes at the same time)
and simplicity (that is, the lock file does not need to be deleted manually by the user).
The two methods are 'file method' and 'socket methods'.
</p>
<h3>File Locking Method 'File'</h3>
The default method for database file locking is the 'File Method'. The algorithm is:
......@@ -462,6 +470,7 @@ the file cannot be locked by any of them) for some time. However, the file never
locked by two threads at the same time. However using that many concurrent threads
/ processes is not the common use case. Generally, an application should throw an error
to the user if it cannot open a database, and not try again in a (fast) loop.
</p>
<h3>File Locking Method 'Socket'</h3>
There is a second locking mechanism implemented, but disabled by default.
......@@ -484,7 +493,7 @@ file every second. The problem with this method is, if the file is stored on a n
share, two processes (running on different computers) could still open the same
database files, if they do not have a direct TCP/IP connection.
<br /><a name="sql_injection"></a>
<br><a name="sql_injection"></a>
<h2>Protection against SQL Injection</h2>
<h3>What is SQL Injection</h3>
This database engine provides a solution for the security vulnerability known as 'SQL Injection'.
......@@ -547,13 +556,14 @@ It is not required to create a constant for the number 0 as there is already a b
SELECT * FROM USERS WHERE LENGTH(PASSWORD)=ZERO();
</pre>
<br /><a name="security_protocols"></a>
<br><a name="security_protocols"></a>
<h2>Security Protocols</h2>
The following paragraphs document the security protocols used in this database.
These descriptions are very technical and only intended for security experts that already know
the underlying security primitives.
<h3>User Password Encryption</h3>
<p>
When a user tries to connect to a database, the combination of
user name, @, and password hashed using SHA-256, and this hash value
is transmitted to the database.
......@@ -565,12 +575,12 @@ That means if a user reuses the same password for different things,
this password is still protected up to some point. See also
'RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication'
for more information.
<p>
</p><p>
When a new database or user is created, a new cryptographically secure
random salt value is generated. The size of the salt is 64 bit.
Using the random salt reduces the risk of an attacker pre-calculating hash values
for many different (commonly used) passwords.
<p>
</p><p>
The combination of user-password hash value (see above) and salt is hashed
using SHA-256. The resulting value is stored in the database.
When a user tries to connect to the database, the database combines
......@@ -582,41 +592,44 @@ spends a lot of time calculating the hash value for each password).
The reasoning is: if the attacker has access to the hashed passwords, he also has
access to the data in plain text, and therefore does not need the password any more.
If the data is protected by storing it on another computer and only remotely, then the iteration count is not required at all.
</p>
<h3>File Encryption</h3>
<p>
The database files can be encrypted using two different algorithms: AES-128 and
XTEA (using 32 rounds). The reasons for supporting XTEA is performance
(XTEA is about twice as fast as AES) and to have an alternative algorithm if
AES is suddenly broken.
<p>
</p><p>
When a user tries to connect to an encrypted database, the combination of the word
'file', @, and the file password is hashed using SHA-256. This hash value is
transmitted to the server.
<p>
</p><p>
When a new database file is created, a new cryptographically secure
random salt value is generated. The size of the salt is 64 bit.
The combination of the file password hash and the salt value is hashed 1024 times
using SHA-256. The reason for the iteration is to make it harder for an attacker to
calculate hash values for common passwords.
<p>
</p><p>
The resulting hash value is used as the key for the block cipher algorithm
(AES-128 or XTEA with 32 rounds). Then, an initialization vector (IV) key
is calculated by hashing the key again using SHA-256.
This is to make sure the IV is unknown to the attacker.
The reason for using a secret IV is to protect against watermark attacks.
<p>
</p><p>
Before saving a block of data (each block is 8 bytes long), the following operations are executed:
First, the IV is calculated by encrypting the block number with the IV key (using the same
block cipher algorithm). This IV is combined with the plain text using XOR. The resulting data is
encrypted using the AES-128 or XTEA algorithm.
<p>
</p><p>
When decrypting, the operation is done in reverse. First, the block is decrypted using the key,
and then the IV is calculated combined with the decrypted text using XOR.
<p>
</p><p>
Therefore, the block cipher modes of operation is CBC (Cipher-block chaining), but each chain
is only one block long. The advantage over the ECB (Electronic codebook) mode is that patterns
in the data are not revealed, and the advantage over multi block CBC is that flipped cipher text bits
are not propagated to flipped plaintext bits in the next block.
</p>
<h3>SSL/TLS Connections</h3>
Remote SSL/TLS connections are supported using the Java Secure Socket Extension
......@@ -628,7 +641,7 @@ The web server supports HTTP and HTTPS connections using SSLServerSocket.
There is a default self-certified certificate to support an easy starting point, but
custom certificates are supported as well.
<br /><a name="uuid"></a>
<br><a name="uuid"></a>
<h2>Universally Unique Identifiers (UUID)</h2>
This database supports UUIDs. Also upported is a function to create new UUIDs using
a cryptographically strong pseudo random number generator.
......@@ -657,7 +670,7 @@ Some values are:
One's annual risk of being hit by a meteorite is estimated to be one chance in 17 billion,
that means the probability is about 0.000'000'000'06.
<br /><a name="system_properties"></a>
<br><a name="system_properties"></a>
<h2>Settings Read from System Properties</h2>
<p>
Some settings of the database can be set on the command line using
......@@ -701,7 +714,7 @@ INFORMATION_SCHEMA.SETTINGS
<tr><td>h2.scriptDirectory</td><td></td><td>Relative or absolute directory where the script files are stored to or read from</td></tr>
</table>
<br /><a name="glossary_links"></a>
<br><a name="glossary_links"></a>
<h2>Glossary and Links</h2>
<table><tr><th>Term</th><th>Description</th></tr>
<tr>
......
......@@ -13,20 +13,20 @@ Build
<h1>Build</h1>
<a href="#portability">
Portability</a><br />
Portability</a><br>
<a href="#environment">
Environment</a><br />
Environment</a><br>
<a href="#building">
Building the Software</a><br />
Building the Software</a><br>
<a href="#maven2">
Using Maven 2</a><br />
Using Maven 2</a><br>
<br /><a name="portability"></a>
<br><a name="portability"></a>
<h2>Portability</h2>
This database is written in Java and therefore works on many platforms.
It is also possible to compile it to a native executable using GCJ.
<br /><a name="environment"></a>
<br><a name="environment"></a>
<h2>Environment</h2>
To build the database executables, the following software stack was used.
In most cases, newer version or compatible software works too, but this was not tested.
......@@ -39,7 +39,7 @@ In most cases, newer version or compatible software works too, but this was not
<li>YourKit Java Profiler
</ul>
<br /><a name="building"></a>
<br><a name="building"></a>
<h2>Building the Software</h2>
On the command line, go to the directory src and execute the following command:
<pre>
......@@ -56,7 +56,7 @@ ant jarClient
</pre>
The other targets may be used as well.
<br /><a name="maven2"></a>
<br><a name="maven2"></a>
<h2>Using Maven 2</h2>
<h3>Using a Central Repository</h3>
You can include the database in your Maven 2 project as a dependency.
......
......@@ -21,8 +21,9 @@ Data Types
<pre>
${item.syntax}
</pre>
${item.text}
<p>
${item.text}
</p>
<b>Example:</b><br>
${item.example}
<br>
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html). -->
<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><title>
H2 Database Engine
</title><link rel="stylesheet" type="text/css" href="stylesheet.css">
<link rel="alternate" type="application/atom+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-atom.xml">
<link rel="alternate" type="application/rss+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-rss.xml">
<script type="text/javascript" src="navigation.js"></script>
</head><body onload="frameMe();">
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>Downloads</h1>
<h3>Version 1.0 / 2007-01-02 (Current)</h3>
<p>
<a href="http://www.h2database.com/h2-setup-2007-01-02.exe">Windows Installer (2.7 MB)</a><br>
<a href="http://www.h2database.com/h2-2007-01-02.zip">Platform-Independent Zip (3.6 MB)</a><br>
</p>
<h3>Version 1.0 / 2006-08-31 (Last Stable)</h3>
<p>
<a href="http://www.h2database.com/h2-setup-2006-08-31.exe">Windows Installer (2.4 MB)</a><br>
<a href="http://www.h2database.com/h2-2006-08-31.zip">Platform-Independent Zip (3.1 MB)</a><br>
</p>
<p>
For details about changes, see the <a href="history.html">Change Log</a>.
</p>
</div></td></tr></table></body></html>
\ No newline at end of file
......@@ -13,59 +13,59 @@ Features
<h1>Features</h1>
<a href="#feature_list">
Feature List</a><br />
Feature List</a><br>
<a href="#comparison">
Comparison to Other Database Engines</a><br />
Comparison to Other Database Engines</a><br>
<a href="#products_work_with">
Products that Work with H2</a><br />
Products that Work with H2</a><br>
<a href="#why_java">
Why Java</a><br />
Why Java</a><br>
<a href="#connection_modes">
Connection Modes</a><br />
Connection Modes</a><br>
<a href="#database_url">
Database URL Overview</a><br />
Database URL Overview</a><br>
<a href="#file_encryption">
Connecting to a Database with File Encryption</a><br />
Connecting to a Database with File Encryption</a><br>
<a href="#database_file_locking">
Database File Locking</a><br />
Database File Locking</a><br>
<a href="#database_only_if_exists">
Opening a Database Only if it Already Exists</a><br />
Opening a Database Only if it Already Exists</a><br>
<a href="#closing_the_database">
Closing the Database</a><br />
Closing the Database</a><br>
<a href="#log_index_changes">
Log Index Changes</a><br />
Log Index Changes</a><br>
<a href="#multiple_connections">
Multiple Connections</a><br />
Multiple Connections</a><br>
<a href="#database_file_layout">
Database File Layout</a><br />
Database File Layout</a><br>
<a href="#logging_recovery">
Logging and Recovery</a><br />
Logging and Recovery</a><br>
<a href="#compatibility_modes">
Compatibility Modes</a><br />
Compatibility Modes</a><br>
<a href="#trace_options">
Using the Trace Options</a><br />
Using the Trace Options</a><br>
<a href="#read_only">
Read Only Databases</a><br />
Read Only Databases</a><br>
<a href="#storage_formats">
Binary and Text Storage Formats</a><br />
Binary and Text Storage Formats</a><br>
<a href="#low_disk_space">
Graceful Handling of Low Disk Space Situations</a><br />
Graceful Handling of Low Disk Space Situations</a><br>
<a href="#computed_columns">
Computed Columns / Function Based Index</a><br />
Computed Columns / Function Based Index</a><br>
<a href="#multi_dimensional">
Multi-Dimensional Indexes</a><br />
Multi-Dimensional Indexes</a><br>
<a href="#passwords">
Using Passwords</a><br />
Using Passwords</a><br>
<a href="#user_defined_functions">
User Defined Functions and Stored Procedures</a><br />
User Defined Functions and Stored Procedures</a><br>
<a href="#triggers">
Triggers</a><br />
Triggers</a><br>
<a href="#compacting">
Compacting a Database</a><br />
Compacting a Database</a><br>
<a href="#cache_settings">
Cache Settings</a><br />
Cache Settings</a><br>
<br /><a name="feature_list"></a>
<br><a name="feature_list"></a>
<h2>Feature List</h2>
<h3>Main Features</h3>
<ul>
......@@ -131,7 +131,7 @@ Features
<li>Well tested (high code coverage, randomized stress tests)
</ul>
<br /><a name="comparison"></a>
<br><a name="comparison"></a>
<h2>Comparison to Other Database Engines</h2>
<table><tr>
......@@ -213,7 +213,7 @@ It looks like the development of this database has stopped. The last release was
<h3>McKoi</h3>
It looks like the development of this database has stopped. The last release was August 2004
<br /><a name="products_work_with"></a>
<br><a name="products_work_with"></a>
<h2>Products that Work with H2</h2>
<table>
<tr><th>Product</th><th>Description</th></tr>
......@@ -275,7 +275,7 @@ It looks like the development of this database has stopped. The last release was
</tr>
</table>
<br /><a name="why_java"></a>
<br><a name="why_java"></a>
<h2>Why Java</h2>
A few reasons using a Java database are:
<ul>
......@@ -285,29 +285,31 @@ A few reasons using a Java database are:
<li>User defined functions (or triggers) run very fast
<li>Unicode support
</ul>
<p>
Some people think that Java is still too slow for low level operations,
but this is not the case (not any more). In general, the code can be written a lot faster
than using C or C++. Like that, it is possible to concentrate on improving the algorithms
(that make the application faster) rather than porting the code and dealing with low
level stuff (such as memory management or dealing with threads).
Garbage collection is now probably faster than manual memory management.
<p>
</p><p>
A lot of features are already built in (for example Unicode, network libraries).
It is very easy to write secure code because buffer overflows and such
problems can be detected very easily. Some features such as the reflection
mechanism can be used for randomized testing.
<p>
</p><p>
Java is also future proof: A lot of companies support Java, and the
open source support for Java is getting better as well (see GCJ).
<p>
</p><p>
This software does not rely on many Java libraries or other software, to
increase the portability and ease of use, and for performance reasons. For example,
the encryption algorithms and many library functions are implemented in the database
instead of using the existing libraries. Libraries that are not available in open source
Java implementations (such as Swing) are not used or only used for specific features
(such as the SysTray library).
</p>
<br /><a name="connection_modes"></a>
<br><a name="connection_modes"></a>
<h2>Connection Modes</h2>
The following connection modes are supported:
<ul>
......@@ -317,10 +319,12 @@ The following connection modes are supported:
<li>In-Memory databases (private and shared)
</ul>
<br /><a name="database_url"></a>
<br><a name="database_url"></a>
<h2>Database URL Overview</h2>
<p>
This database does support multiple connection modes and features when connecting to a database.
This is achieved using different database URLs. The settings in the URLs are not case sensitive.
</p>
<table><tr><th>Topic</th><th>URL Format and Examples</th></tr>
<tr>
<td>Embedded (local) connection</td>
......@@ -429,23 +433,25 @@ directory is used as a starting point. The case sensitivity of the path and data
operating system, however it is suggested to use lowercase letters only.
<h3>Memory-Only Databases</h3>
<p>
For certain use cases (for example: rapid prototyping, testing, high performance
operations, read-only databases), it may not be required to persist (changes to) the data at all.
This database supports the memory-only mode, where the data is not persisted.
<p>
</p><p>
In some cases, only one connection to a memory-only database is required.
This means the database to be opened is private. In this case, the database URL is
<code>jdbc:h2:mem:</code> Opening two connections within the same virtual machine
means opening two different (private) databases.
<p>
</p><p>
Some times multiple connections to the same memory-only database are required.
In this case, the database URL must include a name. Example: <code>jdbc:h2:mem:db1</code>
<p>
</p><p>
It is also possible to open a memory-only database remotely using TCP/IP or SSL/TLS.
An example database URL is: <code>jdbc:h2:tcp://localhost/mem:db1</code>
(using private database remotely is also possible).
</p>
<br /><a name="file_encryption"></a>
<br><a name="file_encryption"></a>
<h2>Connecting to a Database with File Encryption</h2>
To use file encryption, it is required to specify the encryption algorithm (the 'cipher')
and the file password. The algorithm needs to be specified using the connection parameter.
......@@ -463,13 +469,15 @@ conn = DriverManager.
getConnection(url, user, pwds);
</pre>
<br /><a name="database_file_locking"></a>
<br><a name="database_file_locking"></a>
<h2>Database File Locking</h2>
<p>
Whenever a database is opened, a lock file is created to signal other processes
that the database is in use. If database is closed, or if the process that opened
the database terminates, this lock file is deleted.
<p>
</p><p>
The following file locking methods are implemented:
</p>
<ul>
<li>The default method is 'file' and uses a watchdog thread to
protect the database file. The watchdog reads the lock file each second.
......@@ -493,7 +501,7 @@ String url = "jdbc:h2:test;FILE_LOCK=NO";
For more information about the algorithms please see in Advanced Topics under
File Locking Protocol.
<br /><a name="database_only_if_exists"></a>
<br><a name="database_only_if_exists"></a>
<h2>Opening a Database Only if it Already Exists</h2>
By default, when an application calls <code>DriverManager.getConnection(url,...)</code>
and the database specified in the URL does not yet exist, a new (empty) database is created.
......@@ -506,7 +514,7 @@ The complete URL may look like this:
String url = "jdbc:h2:/data/sample;IFEXISTS=TRUE";
</pre>
<br /><a name="closing_the_database"></a>
<br><a name="closing_the_database"></a>
<h2>Closing the Database</h2>
<h3>Delayed Database Closing</h3>
......@@ -537,7 +545,7 @@ The database URL to disable database closing on exit is:
String url = "jdbc:h2:test;DB_CLOSE_ON_EXIT=FALSE";
</pre>
<br /><a name="log_index_changes"></a>
<br><a name="log_index_changes"></a>
<h2>Log Index Changes</h2>
Usually, changes to the index file are not logged for performance.
If the index file is corrupt or missing when opening a database, it is re-created from the data.
......@@ -568,7 +576,7 @@ same as executing the statement <code>SET setting value</code> just after
connecting. For a list of settings supported by this database please see the
SQL grammar documentation.
<br /><a name="multiple_connections"></a>
<br><a name="multiple_connections"></a>
<h2>Multiple Connections</h2>
<h3>Opening Multiple Databases at the Same Time</h3>
......@@ -589,13 +597,14 @@ connections to the same database. The number of open database is only limited by
need to wait.
<h3>Locking, Lock-Timeout, Deadlocks</h3>
<p>
The database uses table level locks to give each connection a consistent state of the data.
There are two kinds of locks: read locks (shared locks) and write locks (exclusive locks).
If a connection wants to reads from a table, and there is no write lock on the table,
then a read lock is added to the table. If there is a write lock, then this connection waits
for the other connection to release the lock. If connection cannot get a lock for a specified time,
then a lock timeout exception is thrown.
<p>
</p><p>
Usually, SELECT statement will generate read locks. This includes subqueries.
Statements that modify data use write locks. It is also possible to lock a table exclusively without modifying data,
using the statement SELECT ... FOR UPDATE.
......@@ -604,6 +613,7 @@ The commands SAVEPOINT and ROLLBACK TO SAVEPOINT don't affect locks.
The locks are also released when the autocommit mode changes, and for connections with
autocommit set to true (this is the default), locks are released after each statement.
Here is an overview on what statements generate what type of lock:
</p>
<table><tr><th>Type of Lock</th><th>SQL Statement</th></tr>
<tr>
<td>
......@@ -650,9 +660,11 @@ The number of seconds until a lock timeout exception is thrown can be
set separately for each connection using the SQL command SET LOCK_TIMEOUT &lt;milliseconds&gt;.
The initial lock timeout (that is the timeout used for new connections) can be set using the SQL command
SET DEFAULT_LOCK_TIMEOUT &lt;milliseconds&gt;. The default lock timeout is persistent.
</p>
<br /><a name="database_file_layout"></a>
<br><a name="database_file_layout"></a>
<h2>Database File Layout</h2>
<p>
There are a number of files created for persistent databases. Other than some databases,
not every table and/or index is stored in its own file. Instead, usually only the following files are created:
A data file, an index file, a log file, and a database lock file (exists only while the database is in use).
......@@ -660,6 +672,7 @@ In addition to that, a file is created for each large object (CLOB/BLOB), a file
and temporary files for large result sets. Then the command SCRIPT can create script files.
If the database trace option is enabled, trace files are created.
The following files can be created by the database:
</p>
<table><tr><th>File Name</th><th>Description</th><th>Number of Files</th></tr>
<tr><td>
test.data.db
......@@ -737,45 +750,52 @@ The following files can be created by the database:
</table>
<h3>Moving and Renaming Database Files</h3>
Database name and location are not stored inside the database names.
<p>
Database name and location are not stored inside the database names.
</p><p>
While a database is closed, the files can be moved to another directory, and they can be renamed
as well (as long as all files start with the same name).
<p>
</p><p>
As there is no platform specific data in the files, they can be moved to other operating systems
without problems.
</p>
<h3>Backup</h3>
<p>
When the database is closed, it is possible to backup the database files. Please note that index
files do not need to be backed up, because they contain redundant data, and will be recreated
automatically if they don't exist.
<p>
</p><p>
To backup data while the database is running, the SQL command SCRIPT can be used.
</p>
<br /><a name="logging_recovery"></a>
<br><a name="logging_recovery"></a>
<h2>Logging and Recovery</h2>
<p>
Whenever data is modified in the database and those changes are committed, the changes are logged
to disk (except for in-memory objects). The changes to the data file itself are usually written
later on, to optimize disk access. If there is a power failure, the data and index files are not up-to-date.
But because the changes are in the log file, the next time the database is opened, the changes that are
in the log file are re-applied automatically.
<p>
</p><p>
Please note that index file updates are not logged by default. If the database is opened and recovery is required,
the index file is rebuilt from scratch.
<p>
</p><p>
There is usually only one log file per database. This file grows until the database is closed successfully,
and is then deleted. Or, if the file gets too big, the database switches to another log file (with a higher id).
It is possible to force the log switching by using the CHECKPOINT command.
<p>
</p><p>
If the database file is corrupted, because the checksum of a record does not match (for example, if the
file was edited with another application), the database can be opened in recovery mode. In this case,
errors in the database are logged but not thrown. The database should be backed up to a script
and re-built as soon as possible. To open the database in the recovery mode, use a database URL
must contain RECOVER=1, as in jdbc:h2:test;RECOVER=1. Indexes are rebuilt in this case, and
the summary (object allocation table) is not read in this case, so opening the database takes longer.
</p>
<br /><a name="compatibility_modes"></a>
<br><a name="compatibility_modes"></a>
<h2>Compatibility Modes</h2>
<p>
All database engines behave a little bit different. For certain features,
this database can emulate the behavior of specific databases. Not all features or differences of those
databases are implemented. Currently, this feature is mainly used for randomized comparative testing
......@@ -784,6 +804,7 @@ The mode can be changed by specifying the mode in the database URL, or using the
To use the HSQLDB mode, you can use the database URL <code>jdbc:h2:test;MODE=HSQLDB</code>
or the SQL statement <code>SET MODE HSQLDB</code>.
Here is the list of currently supported modes and the difference to the regular mode:
</p>
<table>
<tr><th>Mode</th><th>Differences</th></tr>
<tr><td>
......@@ -809,7 +830,7 @@ Here is the list of currently supported modes and the difference to the regular
</td></tr>
</table>
<br /><a name="trace_options"></a>
<br><a name="trace_options"></a>
<h2>Using the Trace Options</h2>
To find problems in an application, it is sometimes good to see what database operations
where executed. This database offers the following trace features:
......@@ -878,21 +899,23 @@ Class.forName("org.h2.Driver");
Also, the user name and password needs to be set, because they are not listed in the trace file.
<h3>Enabling the Trace Option at Runtime by Manually Creating a File</h3>
<p>
Sometimes, you can't or don't want to change the application or database URL.
There is still a way to enable the trace mode in these cases, even at runtime (while
the database connection is open). You only need to create a special file in the directory
where the database files are stored.
The database engine checks every 4 seconds if this file exists (only while executing a statement).
The file name is the database name plus '.trace.db.start'.
<p>
</p><p>
Example: if a database is called 'test', then the file to start tracing is 'test.trace.db.start'.
The database engine tries to delete this file when it detects it.
If trace is enabled using the start file, the trace level is not persistent to the database, and
trace is switched back to the level that was set before when connecting to the database.
However, if the start file is read only, the database engine cannot delete the file and
will always enable the trace mode when connecting.
</p>
<br /><a name="read_only"></a>
<br><a name="read_only"></a>
<h2>Read Only Databases</h2>
If the database files are read-only, then the database is read-only as well.
It is not possible to create new tables, add or modify data in this database.
......@@ -903,7 +926,7 @@ When you open the database now, it is read-only.
There are two ways an application can find out a database is read-only:
By calling Connection.isReadOnly() or by executing the SQL statement CALL READONLY().
<br /><a name="storage_formats"></a>
<br><a name="storage_formats"></a>
<h2>Binary and Text Storage Formats</h2>
This database engine supports both binary and text storage formats.
The binary format is faster, but the text storage format can be useful as well,
......@@ -913,8 +936,9 @@ New databases are created in the binary storage format by default.
To create a new database in the text storage format, the database URL must contain
the parameter STORAGE=TEXT. Example URL: jdbc:h2:test;STORAGE=TEXT
<br /><a name="low_disk_space"></a>
<br><a name="low_disk_space"></a>
<h2>Graceful Handling of Low Disk Space Situations</h2>
<p>
The database is able to deal with situations where the disk space available is running low.
Whenever the database starts, an 'emergency space' file is created (size is 1 MB),
and if there is no more space available, the file will shrink. If the space available
......@@ -923,7 +947,7 @@ writing operations are no longer allowed: All writing operations will throw the
exception 'No disk space available' from this point on. To go back to the normal operating
mode, all connections to the database need to be closed first, and space needs to
be freed up.
<p>
</p><p>
It is possible to install a database event listener to detect low disk space situations early on
(when only 1 MB if space is available). To do this, use the SQL statement
SET DATABASE_EVENT_LISTENER.
......@@ -931,13 +955,14 @@ The listener can also be set at connection time, using an URL of the form
jdbc:h2:test;DATABASE_EVENT_LISTENER='com.acme.DbListener'
(the quotes around the class name are required).
See also the DatabaseEventListener API.
</p>
<h3>Opening a Corrupted Database</h3>
If a database can not be opened because the boot info (the SQL script that is run at startup)
is corrupted, then the database can be opened by specifying a database event listener.
The exceptions are logged, but opening the database will continue.
<br /><a name="computed_columns"></a>
<br><a name="computed_columns"></a>
<h2>Computed Columns / Function Based Index</h2>
Function indexes are not directly supported by this database, but they can be easily emulated
by using computed columns. For example, if an index on the upper-case version of
......@@ -959,19 +984,20 @@ INSERT INTO ADDRESS(ID, NAME) VALUES(1, 'Miller');
SELECT * FROM ADDRESS WHERE UPPER_NAME='MILLER';
</pre>
<br /><a name="multi_dimensional"></a>
<br><a name="multi_dimensional"></a>
<h2>Multi-Dimensional Indexes</h2>
<p>
A tool is provided to execute efficient multi-dimension (spatial) range queries.
This database does not support a specialized spatial index (R-Tree or similar).
Instead, the B-Tree index is used. For each record, the multi-dimensional key
is converted (mapped) to a single dimensional (scalar) value.
This value specifies the location on a space-filling curve.
<p>
</p><p>
Currently, Z-order (also called N-order or Morton-order) is used;
Hilbert curve could also be used, but the implementation is more complex.
The algorithm to convert the multi-dimensional value is called bit-interleaving.
The scalar value is indexed using a B-Tree index (usually using a computed column).
<p>
</p><p>
The method can result in a drastic performance improvement
over just using an index on the first column. Depending on the
data and number of dimensions, the improvement is usually higher than factor 5.
......@@ -979,34 +1005,39 @@ The tool generates a SQL query from a specified multi-dimensional range.
The method used is not database dependent, and the tool can easily be ported to other databases.
For an example how to use the tool, please have a look at the sample code provided
in TestMultiDimension.java.
</p>
<br /><a name="passwords"></a>
<br><a name="passwords"></a>
<h2>Using Passwords</h2>
<h3>Using Secure Passwords</h3>
<p>
Remember that weak passwords can be broken no matter of the encryption and security protocol.
Don't use passwords that can be found in a dictionary. Also appending numbers does not make them
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.
Example:
<p>
</p><p>
i'sE2rTpiUKtt (it's easy to remember this password if you know the trick)
</p>
<h3>Passwords: Using Char Arrays instead of Strings</h3>
<p>
Java Strings are immutable objects and cannot be safely 'destroyed' by the application.
After creating a String, it will remain in the main memory of the computer at least
until it is garbage collected. The garbage collection cannot be controlled by the application,
and even if it is garbage collected the data may still remain in memory.
It might also be possible that the part of memory containing the password
is swapped to disk (because not enough main memory is available).
<p>
</p><p>
An attacker might have access to the swap file of the operating system.
It is therefore a good idea to use char arrays instead of Strings to store passwords.
Char arrays can be cleared (filled with zeros) after use, and therefore the
password will not be stored in the swap file.
<p>
</p><p>
This database supports using char arrays instead of String to pass user and file passwords.
The following code can be used to do that:
</p>
<pre>
Class.forName("org.h2.Driver");
String url = "jdbc:h2:simple";
......@@ -1040,7 +1071,7 @@ Connection conn = DriverManager.
</code>
The settings in the URL override the settings passed as a separate parameter.
<br /><a name="user_defined_functions"></a>
<br><a name="user_defined_functions"></a>
<h2>User Defined Functions and Stored Procedures</h2>
In addition to the built-in functions, this database supports user defined Java functions.
......@@ -1133,7 +1164,7 @@ CREATE ALIAS MATRIX FOR "org.h2.samples.Function.getMatrix";
SELECT * FROM MATRIX(3) WHERE X>0;
</pre>
<br /><a name="triggers"></a>
<br><a name="triggers"></a>
<h2>Triggers</h2>
This database supports Java triggers that are called before or after a row is updated, inserted or deleted.
Triggers can be used for complex consistency checks, or to update related data in the database.
......@@ -1160,7 +1191,7 @@ CREATE TRIGGER INV_INS AFTER INSERT ON INVOICE
</pre>
The trigger can be used to veto a change, by throwing a SQL Exception.
<br /><a name="compacting"></a>
<br><a name="compacting"></a>
<h2>Compacting a Database</h2>
Empty space in the database file is re-used automatically.
To re-build the indexes, the most simple way is to delete the .index.db file
......@@ -1181,7 +1212,7 @@ See also the sample application org.h2.samples.Compact.
The commands SCRIPT / RUNSCRIPT can be used as well to create the a backup
of a database and re-build the database from the script.
<br /><a name="cache_settings"></a>
<br><a name="cache_settings"></a>
<h2>Cache Settings</h2>
<p>
The database keeps most frequently used data and index pages in the main memory.
......@@ -1189,8 +1220,7 @@ The amount of memory used for caching can be changed using the setting
CACHE_SIZE. This setting can be set in the database connection URL
(jdbc:h2:test;CACHE_SIZE=200000), or it can be changed at runtime using
SET CACHE_SIZE size.
</p>
<p>
</p><p>
This database supports two cache page replacement algorithms: LRU (the default) and
2Q. For LRU, the pages that were least frequently used are removed from the
cache if it becomes full. The 2Q algorithm is a bit more complicated, basically two
......@@ -1198,8 +1228,7 @@ queues are used. The 2Q algorithm is more resistent to table scans, however the
is a bit higher compared to the LRU. To use the cache algorithm 2Q, use a database URL
of the form jdbc:h2:test;CACHE_TYPE=TQ. The cache algorithm can not be changed
once the database is open.
</p>
<p>
</p><p>
To get information about page reads and writes, and the current caching algorithm in use,
call SELECT * FROM INFORMATION_SCHEMA.SETTINGS. The number of pages read / written
is listed for the data and index file.
......
......@@ -9,8 +9,8 @@ Initial Developer: H2 Group
<title>H2 Database Engine</title>
<script type="text/javascript" src="navigation.js"></script>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<link rel="alternate" type="application/atom+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-atom.xml" />
<link rel="alternate" type="application/rss+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-rss.xml" />
<link rel="alternate" type="application/atom+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-atom.xml">
<link rel="alternate" type="application/rss+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-rss.xml">
</head>
<frameset cols="180,*" rows="*" frameborder="2" framespacing="4" border="4" onLoad="loadFrameset()">
<frame frameborder="0" marginheight="0" marginwidth="0" src="search.html" name="menu">
......
......@@ -43,8 +43,9 @@ Functions
<pre>
${item.syntax}
</pre>
${item.text}
<p>
${item.text}
</p>
<b>Example:</b><br>
${item.example}
<br>
......
......@@ -34,8 +34,9 @@ SQL Grammar
<pre>
${item.syntax}
</pre>
${item.text}
<p>
${item.text}
</p>
<b>Example:</b><br>
${item.example}
<br>
......@@ -47,8 +48,9 @@ ${item.example}
<pre>
${item.syntax}
</pre>
${item.text}
<p>
${item.text}
</p>
<b>Example:</b><br>
${item.example}
<br>
......
......@@ -12,13 +12,13 @@ History
<h1>History and Roadmap</h1>
<a href="#history">
History of this Database Engine</a><br />
History of this Database Engine</a><br>
<a href="#changelog">
Change Log</a><br />
Change Log</a><br>
<a href="#roadmap">
Roadmap</a><br />
Roadmap</a><br>
<br /><a name="history"></a>
<br><a name="history"></a>
<h2>History of this Database Engine</h2>
The development of H2 was started in May 2004,
but it was first published on December 14th 2005.
......@@ -29,7 +29,7 @@ to continued to work on the Hypersonic SQL codebase.
The name H2 stands for Hypersonic 2; however H2 does not share any code with
Hypersonic SQL or HSQLDB. H2 is built from scratch.
<br /><a name="changelog"></a>
<br><a name="changelog"></a>
<h2>Change Log</h2>
<h3>Version 1.0 (Current)</h3>
......@@ -1349,7 +1349,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
First public release.
</ul>
<br /><a name="roadmap"></a>
<br><a name="roadmap"></a>
<h2>Roadmap</h2>
<h3>Highest Priority</h3>
......
......@@ -13,15 +13,15 @@ Installation
<h1>Installation</h1>
<a href="#requirements">
Requirements</a><br />
Requirements</a><br>
<a href="#supported_platforms">
Supported Platforms</a><br />
Supported Platforms</a><br>
<a href="#installing">
Installing the Software</a><br />
Installing the Software</a><br>
<a href="#directory_structure">
Directory Structure</a><br />
Directory Structure</a><br>
<br /><a name="requirements"></a>
<br><a name="requirements"></a>
<h2>Requirements</h2>
To run the database, the following software stack is known to work.
Compatible software works too, but this was not tested.
......@@ -31,7 +31,7 @@ Compatible software works too, but this was not tested.
<li>Mozilla Firefox 1.5
</ul>
<br /><a name="supported_platforms"></a>
<br><a name="supported_platforms"></a>
<h2>Supported Platforms</h2>
As this database is written in Java, it can be run on many different platforms.
It is tested with Java 1.4 and 1.5, but can also be compiled to native code using GCJ.
......@@ -39,11 +39,11 @@ The source code does not use features of Java 1.5. Currently, the database is
developed and tested on Windows XP using the Sun JDKs, but probably it also
works in many other operating systems and using other Java runtime environments.
<br /><a name="installing"></a>
<br><a name="installing"></a>
<h2>Installing the Software</h2>
To install the software, run the installer or unzip it to a directory of your choice.
<br /><a name="directory_structure"></a>
<br><a name="directory_structure"></a>
<h2>Directory Structure</h2>
<p>
After installing, you should get the following directory structure:
......@@ -52,6 +52,7 @@ After installing, you should get the following directory structure:
<tr>
<th>Directory</th>
<th>Contents</th>
</tr>
<tr>
<td>bin</td>
<td>Executables and JAR files</td>
......
......@@ -22,13 +22,16 @@ There is a License FAQ section at the Mozilla web site, most of that is applicab
<li>Modifications to the H2 source code must be published.
<li>You don't need to provide the source code of H2 if you did not modify anything.
</ul>
<p>
However, nobody is allowed to rename H2, modify it a little, and sell it as a database engine without telling the customers it is in fact H2.
This happened to HSQLDB, when a company called 'bungisoft' copied HSQLDB, renamed it to 'RedBase', and tried to sell it,
hiding the fact that it was, in fact, just HSQLDB. At this time, it seems 'bungisoft' does not exist any more, but you can use the
Wayback Machine of http://www.archive.org and look for old web pages of http://www.bungisoft.com.
<p>
</p><p>
About porting the source code to another language (for example C# or C++): Converted source code (even if done manually) stays under the same
copyright and license as the original code. The copyright of the ported source code does not (automatically) go to the person who ported the code.
</p>
<h2>H2 License, Version 1.0</h2>
......@@ -114,7 +117,7 @@ copyright and license as the original code. The copyright of the ported source c
<h3 id="section-2">2. Source Code License</h3>
<h4 id="section-2.1">2.1. The Initial Developer Grant</h4>
<p>The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
license, subject to third party intellectual property claims:
<ol type="a">
<li id="section-2.1-a">under intellectual property rights (other than patent or
......@@ -136,7 +139,7 @@ copyright and license as the original code. The copyright of the ported source c
</ol>
<h4 id="section-2.2">2.2. Contributor Grant</h4>
<p>Subject to third party intellectual property claims, each Contributor hereby grants You
Subject to third party intellectual property claims, each Contributor hereby grants You
a world-wide, royalty-free, non-exclusive license
<ol type="a">
<li id="section-2.2-a">under intellectual property rights (other than patent or trademark)
......@@ -164,7 +167,7 @@ copyright and license as the original code. The copyright of the ported source c
<h3 id="section-3">3. Distribution Obligations</h3>
<h4 id="section-3.1">3.1. Application of License</h4>
<p>The Modifications which You create or to which You contribute are governed by the terms
The Modifications which You create or to which You contribute are governed by the terms
of this License, including without limitation Section <a href="#section-2.2">2.2</a>. The
Source Code version of Covered Code may be distributed only under the terms of this License
or a future version of this License released under Section <a href="#section-6.1">6.1</a>,
......@@ -174,7 +177,7 @@ copyright and license as the original code. The copyright of the ported source c
However, You may include an additional document offering the additional rights described in
Section <a href="#section-3.5">3.5</a>.
<h4 id="section-3.2">3.2. Availability of Source Code</h4>
<p>Any Modification which You create or to which You contribute must be made available in
Any Modification which You create or to which You contribute must be made available in
Source Code form under the terms of this License either on the same media as an Executable
version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an
Executable version available; and if made available via Electronic Distribution Mechanism,
......@@ -185,7 +188,7 @@ copyright and license as the original code. The copyright of the ported source c
Mechanism is maintained by a third party.
<h4 id="section-3.3">3.3. Description of Modifications</h4>
<p>You must cause all Covered Code to which You contribute to contain a file documenting the
You must cause all Covered Code to which You contribute to contain a file documenting the
changes You made to create that Covered Code and the date of any change. You must include a
prominent statement that the Modification is derived, directly or indirectly, from Original
Code provided by the Initial Developer and including the name of the Initial Developer in
......@@ -215,7 +218,7 @@ copyright and license as the original code. The copyright of the ported source c
rights conveyed by this License.
</ol>
<h4 id="section-3.5">3.5. Required Notices</h4>
<p>You must duplicate the notice in <a href="#exhibit-a">Exhibit A</a> in each file of the
You must duplicate the notice in <a href="#exhibit-a">Exhibit A</a> in each file of the
Source Code. If it is not possible to put such notice in a particular Source Code file due to
its structure, then You must include such notice in a location (such as a relevant directory)
where a user would be likely to look for such a notice. If You created one or more
......@@ -230,7 +233,7 @@ copyright and license as the original code. The copyright of the ported source c
and every Contributor for any liability incurred by the Initial Developer or such Contributor
as a result of warranty, support, indemnity or liability terms You offer.
<h4 id="section-3.6">3.6. Distribution of Executable Versions</h4>
<p>You may distribute Covered Code in Executable form only if the requirements of Sections
You may distribute Covered Code in Executable form only if the requirements of Sections
<a href="#section-3.1">3.1</a>, <a href="#section-3.2">3.2</a>,
<a href="#section-3.3">3.3</a>, <a href="#section-3.4">3.4</a> and
<a href="#section-3.5">3.5</a> have been met for that Covered Code, and if You include a
......@@ -250,11 +253,11 @@ copyright and license as the original code. The copyright of the ported source c
a result of any such terms You offer.
<h4 id="section-3.7">3.7. Larger Works</h4>
<p>You may create a Larger Work by combining Covered Code with other code not governed by the
You may create a Larger Work by combining Covered Code with other code not governed by the
terms of this License and distribute the Larger Work as a single product. In such a case,
You must make sure the requirements of this License are fulfilled for the Covered Code.
<h3 id="section-4">4. Inability to Comply Due to Statute or Regulation.</h3>
<p>If it is impossible for You to comply with any of the terms of this License with respect to
If it is impossible for You to comply with any of the terms of this License with respect to
some or all of the Covered Code due to statute, judicial order, or regulation then You must:
(a) comply with the terms of this License to the maximum extent possible; and (b) describe
the limitations and the code they affect. Such description must be included in the
......@@ -263,21 +266,21 @@ copyright and license as the original code. The copyright of the ported source c
Except to the extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to understand it.
<h3 id="section-5">5. Application of this License.</h3>
<p>This License applies to code to which the Initial Developer has attached the notice in
This License applies to code to which the Initial Developer has attached the notice in
<a href="#exhibit-a">Exhibit A</a> and to related Covered Code.
<h3 id="section-6">6. Versions of the License.</h3>
<h4 id="section-6.1">6.1. New Versions</h4>
<p>The <u>H2 Group</u> may publish revised and/or new versions
The <u>H2 Group</u> may publish revised and/or new versions
of the License from time to time. Each version will be given a distinguishing version number.
<h4 id="section-6.2">6.2. Effect of New Versions</h4>
<p>Once Covered Code has been published under a particular version of the License, You may
Once Covered Code has been published under a particular version of the License, You may
always continue to use it under the terms of that version. You may also choose to use such
Covered Code under the terms of any subsequent version of the License published by the <u>H2 Group</u>.
No one other than the <u>H2 Group</u> has the right to modify the terms applicable to Covered Code
created under this License.
<h4 id="section-6.3">6.3. Derivative Works</h4>
<p>If You create or use a modified version of this License (which you may only do in order to
If You create or use a modified version of this License (which you may only do in order to
apply it to code which is not already Covered Code governed by this License), You must (a)
rename Your license so that the phrases <u>"H2 Group", "H2"</u>
or any confusingly similar phrase do not appear in your license (except to note that
......@@ -287,7 +290,7 @@ copyright and license as the original code. The copyright of the ported source c
notice described in <a href="#exhibit-a">Exhibit A</a> shall not of themselves be deemed to
be modifications of this License.)
<h3 id="section-7">7. Disclaimer of Warranty</h3>
<p>Covered code is provided under this license on an "as is"
Covered code is provided under this license on an "as is"
basis, without warranty of any kind, either expressed or implied, including, without
limitation, warranties that the covered code is free of defects, merchantable, fit for a
particular purpose or non-infringing. The entire risk as to the quality and performance of
......@@ -302,10 +305,13 @@ copyright and license as the original code. The copyright of the ported source c
within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which
are properly granted shall survive any termination of this License. Provisions which, by
their nature, must remain in effect beyond the termination of this License shall survive.
</p>
<p id="section-8.2">8.2. If You initiate litigation by asserting a patent infringement
claim (excluding declaratory judgment actions) against Initial Developer or a Contributor
(the Initial Developer or Contributor against whom You file such action is referred to
as "Participant") alleging that:
</p>
<ol type="a">
<li id="section-8.2-a">such Participant's Contributor Version directly or indirectly
infringes any patent, then any and all rights granted by such Participant to You under
......@@ -326,6 +332,7 @@ copyright and license as the original code. The copyright of the ported source c
and 2.2(<a href="#section-2.2-b">b</a>) are revoked effective as of the date You first
made, used, sold, distributed, or had made, Modifications made by that Participant.
</ol>
<p id="section-8.3">8.3. If You assert a patent infringement claim against Participant
alleging that such Participant's Contributor Version directly or indirectly infringes
any patent where such claim is resolved (such as by license or settlement) prior to the
......@@ -333,14 +340,18 @@ copyright and license as the original code. The copyright of the ported source c
granted by such Participant under Sections <a href="#section-2.1">2.1</a> or
<a href="#section-2.2">2.2</a> shall be taken into account in determining the amount or
value of any payment or license.
</p>
<p id="section-8.4">8.4. In the event of termination under Sections
<a href="#section-8.1">8.1</a> or <a href="#section-8.2">8.2</a> above, all end user
license agreements (excluding distributors and resellers) which have been validly
granted by You or any distributor hereunder prior to termination shall survive
termination.
</p>
<h3 id="section-9">9. Limitation of Liability</h3>
<p>Under no circumstances and under no legal theory, whether
Under no circumstances and under no legal theory, whether
tort (including negligence), contract, or otherwise, shall you, the initial developer,
any other contributor, or any distributor of covered code, or any supplier of any of
such parties, be liable to any person for any indirect, special, incidental, or
......@@ -353,14 +364,14 @@ copyright and license as the original code. The copyright of the ported source c
or limitation of incidental or consequential damages, so this exclusion and limitation
may not apply to you.
<h3 id="section-10">10. United States Government End Users</h3>
<p>The Covered Code is a "commercial item", as that term is defined in 48
The Covered Code is a "commercial item", as that term is defined in 48
C.F.R. 2.101 (October 1995), consisting of
"commercial computer software" and "commercial computer software documentation", as such
terms are used in 48 C.F.R. 12.212 (September 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R.
227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users
acquire Covered Code with only those rights set forth herein.
<h3 id="section-11">11. Miscellaneous</h3>
<p>This License represents the complete agreement concerning subject matter hereof. If
This License represents the complete agreement concerning subject matter hereof. If
any provision of this License is held to be unenforceable, such provision shall be
reformed only to the extent necessary to make it enforceable. This License shall be
governed by <u>Swiss</u> law provisions (except to the extent applicable law, if any,
......@@ -375,13 +386,13 @@ copyright and license as the original code. The copyright of the ported source c
shall be construed against the drafter shall not apply to this License.
<h3 id="section-12">12. Responsibility for Claims</h3>
<p>As between Initial Developer and the Contributors, each party is responsible for
As between Initial Developer and the Contributors, each party is responsible for
claims and damages arising, directly or indirectly, out of its utilization of rights
under this License and You agree to work with Initial Developer and Contributors to
distribute such responsibility on an equitable basis. Nothing herein is intended or
shall be deemed to constitute any admission of liability.
<h3 id="section-13">13. Multiple-Licensed Code</h3>
<p>Initial Developer may designate portions of the Covered Code as
Initial Developer may designate portions of the Covered Code as
"Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits
you to utilize portions of the Covered Code under Your choice of this
or the alternative licenses, if any, specified by the Initial Developer in the file
......
......@@ -11,10 +11,10 @@ H2 Database Engine
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>H2 Database Engine</h1>
<p>
Welcome to H2, the free SQL database engine.
</p>
<p>
<a href="quickstartText.html" style="font-size: 16px; font-weight: bold">Quickstart</a>
<br>
Click here to get a fast overview.
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html). -->
<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><title>
H2 Database Engine
</title><link rel="stylesheet" type="text/css" href="stylesheet.css">
<link rel="alternate" type="application/atom+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-atom.xml">
<link rel="alternate" type="application/rss+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-rss.xml">
<script type="text/javascript" src="navigation.js"></script>
</head><body onload="frameMe();">
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>H2 Database Engine</h1>
<p>
Welcome to H2, the free SQL database. The main feature of H2 are:
</p>
<ul>
<li>Very fast, free for everybody, source code is included
<li>Written Java; can be compiled with GCJ (Linux)
<li>Embedded, Server and Cluster modes
<li>JDBC and (partial) ODBC API; Web Client application
</ul>
<table style="border: 0px;">
<tr><td style="background-color: #eee;">
<table style="border: 0px; margin: 5px; background-color: #eee;">
<tr><td style="border: 0px; background-color: #eee;" colspan="2">
<h3>Download</h3>
Version 1.0 / 2007-01-02:
</td></tr>
<tr><td style="border: 0px; background-color: #eee;">
<a href="http://www.h2database.com/h2-setup-2007-01-02.exe"><img border="1" src="images/download.png" alt="download"></a>
</td><td style="vertical-align: middle; border: 0px; background-color: #eee;">
<a href="http://www.h2database.com/h2-setup-2007-01-02.exe">Windows Installer (2.7 MB)</a>
</td></tr>
<tr><td style="border: 0px; background-color: #eee;">
<a href="http://www.h2database.com/h2-2007-01-02.zip"><img border="1" src="images/download.png" alt="download"></a>
</td><td style="vertical-align: middle; border: 0px; background-color: #eee;">
<a href="http://www.h2database.com/h2-2007-01-02.zip">Platform-Independent Zip (3.6 MB)</a>
</td></tr>
<tr><td style="border: 0px; background-color: #eee;" colspan="2">
<a href="download.html">All Downloads</a>
</td></tr>
</table>
</td><td style="border: 0px;">&nbsp;&nbsp;&nbsp;</td>
<td style="background-color: #eee;">
<table style="border: 0px; margin: 5px;">
<tr><td style="border: 0px; background-color: #eee;">
<h3>Support</h3>
<p>
<a href="http://www.h2database.com/ipowerb" target="_top">Forums: Help and Open Discussion</a><br><br>
Or send an e-mail to: <br>
<script type="text/javascript">
<!--
var a = '-support.png';
var b = 'mail';
var c = 'support ';
var d = 'db';
var e = 'at ';
var f = '.com';
var g = 'h2database';
var alt = 'mail address: ' + d + c + e + g + f + '(without spaces)';
document.write('<' + ' a h'+'ref="em' + 'ail:' + d + c + e + g + f +'">' + d + c + e + g + f);
//-->
</script>
<!--
The forum doesn't work at the moment, sorry. <br>
But you can send an e-mail to: <p>
<script type="text/javascript">
var a = '-support.png';
var b = 'mail';
var c = 'support ';
var d = 'db';
var e = 'at ';
var f = '.com';
var g = 'h2database';
var alt = 'mail address: ' + d + c + e + g + f + '(without spaces)';
document.write('<'+'a h' + 'ref="em' + 'ail:' + d + c + e + g + f +'">' + d + c + e + g + f);
</script>
-->
</p>
</td></tr>
</table>
</td></tr>
<tr><td colspan="3" style="border: 0px">&nbsp;</td></tr>
<tr><td colspan="3" style="border: 0px">
<table style="border: 0px; margin: 5px; width: 100%;">
<tr><td style="border: 0px;" >
<h3>Performance</h3>
<img border="0" src="images/performance.png" alt="Performance comparison"><br>
Operations/second (higher is better) - <a href="performance.html">More information about this test</a>
</td></tr>
</table>
</td></tr>
<tr><td colspan="3" style="border: 0px">&nbsp;</td></tr>
<tr><td colspan="3" style="background-color: #eee;">
<table style="border: 0px; margin: 5px; background-color: #eee;">
<tr><td style="border: 0px; background-color: #eee;">
<h3>News</h3>
<p>
<b>Email Subscription</b>: If you like to get informed by email about new releases, <br>
subscribe here. The email addresses of members are only used in this context.<br>
Usually, only one mail every few weeks will be sent.
</p>
<form name="newsletter" method="post" action="php/newsletter.php">
Email: <input type="email" name="email" size="30" onKeyDown="newsletter.spam.value='false';">
<input type="hidden" name="spam" value="true" size="30">
<input type="hidden" name="text" value="subscribe">
<input type="submit" value="Submit">
<br><br>
<b>Newsfeeds:</b> Two are available:
<a href="http://www.h2database.com/html/newsfeed-atom.xml" target="_blank">Full text (Atom)</a>
and <a href="http://www.h2database.com/html/newsfeed-rss.xml" target="_blank">Header only (RSS)</a>.<br>
If you need a newsreader: <a href="http://rssowl.sf.net">RSSOwl</a>.
</form>
</td></tr>
</table>
</td></tr>
<tr><td colspan="3" style="border: 0px">&nbsp;</td></tr>
<tr><td colspan="3" style="background-color: #eee;">
<table style="border: 0px; margin: 5px;">
<tr><td style="border: 0px; background-color: #eee;">
<h3>Feedback</h3>
You may also send questions, feature requests, or feedback of any kind here:
<form method="post" action="php/sendMail.php">
<p>
Email (optional):<br>
<input name="email" size="73" type="email">
</p><p>
Message:<br>
<textarea name="text" cols="70" rows="5"></textarea>
<br>
<input value="Submit" type="submit">
</p>
</form>
</td></tr>
</table>
</td></tr>
<tr><td colspan="3" style="border: 0px">&nbsp;</td></tr>
<tr><td colspan="3" style="background-color: #eee;">
<table style="border: 0px; margin: 5px;">
<tr><td style="border: 0px; background-color: #eee;">
<h3>Donations</h3>
Click on one of the PayPal buttons below to donate money to H2.
You will be listed as a supporter.
Other ways to contribute to the development of H2 is sending feedback
and bug reports, or translate the H2 Console application
(files h2/src/main/org/h2/server/web/res/_text_*.properties).
</td></tr>
</table>
</td></tr>
</table>
</div></td></tr></table></body></html>
\ No newline at end of file
......@@ -12,13 +12,13 @@ Performance
<h1>Performance</h1>
<a href="#performance_comparison">
Performance Comparison</a><br />
Performance Comparison</a><br>
<a href="#application_profiling">
Application Profiling</a><br />
Application Profiling</a><br>
<a href="#database_performance_tuning">
Performance Tuning</a><br />
Performance Tuning</a><br>
<br /><a name="performance_comparison"></a>
<br><a name="performance_comparison"></a>
<h2>Performance Comparison</h2>
In most cases H2 is a lot faster than all other
......@@ -218,7 +218,7 @@ and for each step a new connection is opened and then closed.
That means the Open/Close time listed is for opening a connection
if the database is already in use.
<br /><a name="application_profiling"></a>
<br><a name="application_profiling"></a>
<h2>Application Profiling</h2>
<h3>Analyze First</h3>
......@@ -232,7 +232,7 @@ A very good tool to measure both the memory and the CPU is the
<a href="http://www.yourkit.com">YourKit Java Profiler</a>. This tool is also used
to optimize the performance and memory footprint of this database engine.
<br /><a name="database_performance_tuning"></a>
<br><a name="database_performance_tuning"></a>
<h2>Database Performance Tuning</h2>
<h3>Virus Scanners</h3>
......@@ -280,11 +280,12 @@ However, this is only possible if no WHERE clause is used, that means it only wo
queries of the form SELECT COUNT(*) FROM table.
<h3>Updating Optimizer Statistics / Column Selectivity</h3>
<p>
When executing a query, at most one index per joined table can be used.
If the same table is joined multiple times, for each join only one index is used.
Example: for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME='A' AND T2.ID=T1.ID,
two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
<p>
</p><p>
If a table has multiple indexes, sometimes more than one index could be used.
Example: if there is a table TEST(ID, NAME, FIRSTNAME) and an index on each column,
then two indexes could be used for the query SELECT * FROM TEST WHERE NAME='A' AND FIRSTNAME='B',
......@@ -293,8 +294,9 @@ Which index is used depends on the selectivity of the column. The selectivity de
values in a column. A selectivity of 100 means each value appears only once, and a selectivity of 1 means
the same value appears in many or most rows. For the query above, the index on NAME should be used
if the table contains more distinct names than first names.
<p>
</p><p>
The SQL statement ANALYZE can be used to automatically estimate the selectivity of the columns in the tables.
This command should be run from time to time to improve the query plans generated by the optimizer.
</p>
</div></td></tr></table></body></html>
\ No newline at end of file
......@@ -3,10 +3,10 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Search</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="search.js"></script>
<script type="text/javascript" src="navigation.js"></script>
......@@ -14,7 +14,7 @@ Initial Developer: H2 Group
<body style="margin: 10px 0px 0px 0px;" onload="frameMe('menu');">
<div class="menu">
<img border="0" src="h2-logo.png" alt="H2 Logo" onclick="document.location='main.html'"/>
<img border="0" src="h2-logo.png" alt="H2 Logo" onclick="document.location='main.html'">
</div>
<form name="searchForm" action="submit" onsubmit="return goFirst();">
......@@ -67,4 +67,4 @@ Initial Developer: H2 Group
<br>
</div>
</body>
</body></html>
......@@ -41,7 +41,6 @@ h2 {
h3 {
font-size: 10pt;
margin-bottom: 5px;
}
h4 {
......
......@@ -41,7 +41,6 @@ h2 {
h3 {
font-size: 10pt;
margin-bottom: 5px;
}
h4 {
......
......@@ -12,43 +12,44 @@ Tutorial
<h1>Tutorial</h1>
<a href="#tutorial_starting_h2_console">
Starting and Using the H2 Console</a><br />
Starting and Using the H2 Console</a><br>
<a href="#connecting_using_jdbc">
Connecting to a Database using JDBC</a><br />
Connecting to a Database using JDBC</a><br>
<a href="#creating_new_databases">
Creating New Databases</a><br />
Creating New Databases</a><br>
<a href="#using_server">
Using the Server</a><br />
Using the Server</a><br>
<a href="#using_hibernate">
Using Hibernate</a><br />
Using Hibernate</a><br>
<a href="#web_applications">
Using Databases in Web Applications</a><br />
Using Databases in Web Applications</a><br>
<a href="#csv">
CSV (Comma Separated Values) Support</a><br />
CSV (Comma Separated Values) Support</a><br>
<a href="#upgrade_backup_restore">
Upgrade, Backup, and Restore</a><br />
Upgrade, Backup, and Restore</a><br>
<a href="#openoffice">
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>
<h2>Starting and Using the H2 Console</h2>
<p>
This application lets you access a SQL database using a browser interface.
This can be a H2 database, or another database that supports the JDBC API.
<br>
</p>
<img src="console.png" alt="Web Browser - H2 Console Server - H2 Database">
<br>
This is a client / server application, so both a server and a client are required to run it.
<p>
This is a client / server application, so both a server and a client are required to run it.
</p><p>
Depending on your platform and environment, there are multiple ways to start the application:
<table><tr><th>OS</th><th>Java</th><th>Start</th>
</p>
<table><tr><th>OS</th><th>Java</th><th>Start</th></tr>
<tr>
<td>Windows</td>
<td>1.4 or 1.5</td>
<td>
Click [Start], [All Programs], [H2], and [H2 Console]<br>
If this worked correctly, an icon will be added to the system tray:
<img src="h2.png" alt="[H2 icon]"/><br>
<img src="h2.png" alt="[H2 icon]"><br>
If you don't get the system tray icon, then maybe Java is not installed correctly (in this case, try another way to start the application).
A browser window should open
and point to the Login page (URL: <a href="http://localhost:8082" target="_blank">http://localhost:8082</a>).
......@@ -78,15 +79,17 @@ java -cp h2.jar org.h2.tools.Server
</table>
<h3>Firewall</h3>
<p>
If you start the server, you may get a security warning from the firewall (if you have installed one).
If you don't want other computers in the network to access the database on your machine, you can
let the firewall block those connections. The connection from the local machine will still work.
Only if you want other computers to access the database on this computer, you need allow remote connections
in the firewall.
<p>
</p><p>
Please not that a small firewall is already built into the server. This mechanism by default does not
allow other computer to connect to the server. This can be changed in the Preferences
(Allow connections from other computers).
</p>
<h3>Native Version</h3>
The native version does not require Java, because it is compiled using GCJ.
......@@ -139,26 +142,31 @@ For Windows installations, this file will be in the directory <code>C:\Documents
This file contains the settings of the application.
<h3>Login</h3>
<p>
At the login page, you need to provide connection information to connect to a database.
Set the JDBC driver class of your database, the JDBC URL, user name and password.
If you are done, click [Connect].
<p>
</p><p>
You can save and reuse previously saved settings. The settings are stored in the
Application Properties file.
</p>
<h3>Error Messages</h3>
Error messages in are shown in red. You can show/hide the stack trace of the exception
by clicking on the message.
<h3>Adding Database Drivers</h3>
<p>
Additional database drivers can be registered by adding the Jar file location of the driver to the environment
variables H2DRIVERS or CLASSPATH. Example (Windows): To add the database driver library
C:\Programs\hsqldb\lib\hsqldb.jar, set the environment variable H2DRIVERS to
C:\Programs\hsqldb\lib\hsqldb.jar.<p>
C:\Programs\hsqldb\lib\hsqldb.jar.
</p><p>
Multiple drivers can be set; each entry needs to be separated with a ';' (Windows) or ':' (other operating systems).
Spaces in the path names are supported. The settings must not be quoted.
<p>
</p><p>
Only the Java version supports additional drivers (this feature is not supported by the Native version).
</p>
<h3>Using the Application</h3>
The application has three main panels, the toolbar on top, the tree on the left and the query / result panel on the right.
......@@ -172,14 +180,17 @@ While typing a query, the table that was used is automatically expanded in the t
For, example if you type 'SELECT * FROM TEST T WHERE T.' then the table TEST is automatically expanded in the tree.
<h3>Disconnecting and Stopping the Application</h3>
<p>
On the browser, click 'Disconnect' on the toolbar panel. You will be logged out of the database.
However, the server is still running and ready to accept new sessions.<p>
However, the server is still running and ready to accept new sessions.
</p><p>
To stop the server, right click on the system tray icon and select [Exit].
If you don't have the icon (because you started it in another way),
press [Ctrl]+[C] on the console where the server was started (Windows),
or close the console window.
</p>
<br /><a name="connecting_using_jdbc"></a>
<br><a name="connecting_using_jdbc"></a>
<h2>Connecting to a Database using JDBC</h2>
To connect to a database, a Java application first needs to load the database driver,
and then get a connection. A simple way to do that is using the following code:
......@@ -203,12 +214,12 @@ to be recognized by this database. The second parameter in the <code>getConnecti
is the user name ('sa' for System Administrator in this example). The third parameter is the password.
Please note that in this database, user names are not case sensitive, but passwords are case sensitive.
<br /><a name="creating_new_databases"></a>
<br><a name="creating_new_databases"></a>
<h2>Creating New Databases</h2>
By default, if the database specified in the URL does not yet exist, a new (empty)
database is created automatically.
<br /><a name="using_server"></a>
<br><a name="using_server"></a>
<h2>Using the Server</h2>
H2 currently supports three servers: a Web Server, a TCP Server and an ODBC Server.
The servers can be started in different ways.
......@@ -267,14 +278,14 @@ This function should be called after all connection to the databases are closed
to avoid recovery when the databases are opened the next time.
To stop remote server, remote connections must be enabled on the server.
<br /><a name="using_hibernate"></a>
<br><a name="using_hibernate"></a>
<h2>Using Hibernate</h2>
This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect,
or the native H2 Dialect that is available in the file src/tools/org/h2/tools/hibernate/H2Dialect.txt.
This dialect will be integrated into Hibernate, but until this is done you need to copy the file
into the folder src\org\hibernate\dialect (Hibernate 3.1), rename it to H2Dialect.java and re-compile hibernate.
<br /><a name="web_applications"></a>
<br><a name="web_applications"></a>
<h2>Using Databases in Web Applications</h2>
There are multiple ways to access a database from within web
applications. Here are some examples if you use Tomcat or JBoss.
......@@ -345,7 +356,7 @@ public class DbStarter implements ServletContextListener {
}
</pre>
<br /><a name="csv"></a>
<br><a name="csv"></a>
<h2>CSV (Comma Separated Values) Support</h2>
The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE,
and the CSV library can be used outside the database as a standalone tool.
......@@ -393,7 +404,7 @@ while(rs.next()) {
rs.close();
</pre>
<br /><a name="upgrade_backup_restore"></a>
<br><a name="upgrade_backup_restore"></a>
<h2>Upgrade, Backup, and Restore</h2>
<h3>Database Upgrade</h3>
......@@ -427,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
need to be available on the server side.
<br /><a name="openoffice"></a>
<br><a name="openoffice"></a>
<h2>Using OpenOffice Base</h2>
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.
......
......@@ -2,7 +2,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>H2 Database Engine</title>
<link rel="stylesheet" type="text/css" href="html/stylesheet.css">
......@@ -15,6 +15,7 @@ Initial Developer: H2 Group
<h1>H2 Database Engine</h1>
<p>
Welcome to H2, the free SQL database. The main feature of H2 are:
</p>
<ul>
<li>It is free to use for everybody, source code is included
<li>Written in Java, but also available as native executable
......@@ -23,15 +24,15 @@ Welcome to H2, the free SQL database. The main feature of H2 are:
<li>Clustering is supported
<li>A web client is included
</ul>
</p>
<h2>No Javascript</h2>
<p>
If you are not automatically redirected to the main page, then
Javascript is currently disabled or your browser does not support Javascript.
Some features (for example the integrated search) require Javascript.
<p>
</p><p>
Please enable Javascript, or go ahead without it:
<p>
<a href="html/frame.html" style="font-size: 16px; font-weight: bold">H2 Database Engine</a>
</p>
</body>
</body></html>
......@@ -5,9 +5,9 @@ Initial Developer: H2 Group
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>H2 Documentation</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>
......@@ -36,7 +36,7 @@ Initial Developer: H2 Group
<a href="org/h2/jdbc/JdbcStatement.html" target="javadoc">Statement</a><br>
<br>
<b>Tools</b></br>
<b>Tools</b><br>
Package org.h2.tools<br>
<a href="org/h2/tools/Backup.html" target="javadoc">Backup</a><br>
<a href="org/h2/tools/ChangePassword.html" target="javadoc">ChangePassword</a><br>
......@@ -53,7 +53,7 @@ Package org.h2.tools<br>
<a href="org/h2/tools/SimpleRowSource.html" target="javadoc">SimpleRowSource</a><br>
<br>
<b>Interfaces</b></br>
<b>Interfaces</b><br>
Package org.h2.api<br>
<a href="org/h2/api/DatabaseEventListener.html" target="javadoc">DatabaseEventListener</a><br>
<a href="org/h2/api/Trigger.html" target="javadoc">Trigger</a><br>
......@@ -62,4 +62,4 @@ Package org.h2.api<br>
</div>
</div></td></tr></table>
</body>
</body></html>
......@@ -5,9 +5,9 @@ Initial Developer: H2 Group
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>API Overview</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>
<table style="width: 100%; height: 100%; border: 0px;">
......
......@@ -32,7 +32,6 @@ h2 {
h3 {
font-size: 11pt;
margin-bottom: 5px;
}
h4 {
......
......@@ -564,10 +564,10 @@ public class AppThread extends WebServerThread {
int level = Integer.parseInt(s);
conn.setTransactionIsolation(level);
}
result = "Transaction Isolation: " + conn.getTransactionIsolation() + "<br />";
result += Connection.TRANSACTION_READ_UNCOMMITTED + ": READ_UNCOMMITTED<br />";
result += Connection.TRANSACTION_READ_COMMITTED + ": READ_COMMITTED<br />";
result += Connection.TRANSACTION_REPEATABLE_READ + ": REPEATABLE_READ<br />";
result = "Transaction Isolation: " + conn.getTransactionIsolation() + "<br>";
result += Connection.TRANSACTION_READ_UNCOMMITTED + ": READ_UNCOMMITTED<br>";
result += Connection.TRANSACTION_READ_COMMITTED + ": READ_COMMITTED<br>";
result += Connection.TRANSACTION_REPEATABLE_READ + ": REPEATABLE_READ<br>";
result += Connection.TRANSACTION_SERIALIZABLE + ": SERIALIZABLE";
} else if(sql.startsWith("@SET MAXROWS ")) {
int maxrows = Integer.parseInt(sql.substring("@SET MAXROWS ".length()));
......@@ -588,10 +588,10 @@ public class AppThread extends WebServerThread {
String s = (String) list.get(i);
if(!s.startsWith("@")) {
buff.append(PageParser.escapeHtml(s+";"));
buff.append("<br />");
buff.append("<br>");
}
buff.append(getResult(conn, i+1, s, list.size()==1));
buff.append("<br />");
buff.append("<br>");
}
result = buff.toString();
}
......
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -120,4 +120,4 @@ Initial Developer: H2 Group
</p>
</form>
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -49,4 +49,4 @@ Initial Developer: H2 Group
//-->
</script>
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -12,4 +12,4 @@ Initial Developer: H2 Group
<p class="error">
${error}
</p>
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -16,15 +16,15 @@ Initial Developer: H2 Group
><img src="icon_disconnect.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.disconnect}" title="${text.toolbar.disconnect}" border="1"/></a
class="icon" alt="${text.toolbar.disconnect}" title="${text.toolbar.disconnect}" border="1"></a
><img src="icon_line.gif" class="iconLine" alt=""
/><a href="tables.do?jsessionid=${sessionId}" target="h2menu"
><a href="tables.do?jsessionid=${sessionId}" target="h2menu"
><img src="icon_refresh.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.refresh}" title="${text.toolbar.refresh}" border="1"/></a
class="icon" alt="${text.toolbar.refresh}" title="${text.toolbar.refresh}" border="1"></a
><img src="icon_line.gif" class="iconLine" alt=""
/></td><td class="toolbar"><input type="checkbox" name="autocommit" value="autocommit"
></td><td class="toolbar"><input type="checkbox" name="autocommit" value="autocommit"
onclick="javascript:if(document.header.autocommit.checked)
top.frames['h2result'].document.location='query.do?jsessionid=${sessionId}&amp;sql=@AUTOCOMMIT+TRUE';
else
......@@ -35,14 +35,14 @@ Initial Developer: H2 Group
><img src="icon_rollback.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.rollback}" title="${text.toolbar.rollback}" border="1"/></a
class="icon" alt="${text.toolbar.rollback}" title="${text.toolbar.rollback}" border="1"></a
><a href="query.do?jsessionid=${sessionId}&amp;sql=COMMIT" target="h2result"
><img src="icon_commit.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.commit}" title="${text.toolbar.commit}" border="1"/></a
class="icon" alt="${text.toolbar.commit}" title="${text.toolbar.commit}" border="1"></a
><img src="icon_line.gif" class="iconLine" alt=""
/></td><td class="toolbar">&nbsp;${text.toolbar.maxRows}:&nbsp;</td><td class="toolbar"
></td><td class="toolbar">&nbsp;${text.toolbar.maxRows}:&nbsp;</td><td class="toolbar"
><select name="rowcount" size="1"
onchange="javascript:top.frames['h2result'].document.location='query.do?jsessionid=${sessionId}&amp;sql=@SET+MAXROWS+'+header.rowcount.value;"
><option value="0">${text.toolbar.all}</option>
......@@ -55,20 +55,20 @@ Initial Developer: H2 Group
><img src="icon_run.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.run}" title="${text.toolbar.run}" border="1"/></a
class="icon" alt="${text.toolbar.run}" title="${text.toolbar.run}" border="1"></a
></td><td class="toolbar"><a href="query.do?jsessionid=${sessionId}&amp;sql=@CANCEL" target="h2result"
><img src="icon_stop.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.cancelStatement}" title="${text.toolbar.cancelStatement}" border="1"/></a
class="icon" alt="${text.toolbar.cancelStatement}" title="${text.toolbar.cancelStatement}" border="1"></a
><img src="icon_line.gif" class="iconLine" alt=""
/><a href="query.do?jsessionid=${sessionId}&amp;sql=@HISTORY" target="h2result"
><a href="query.do?jsessionid=${sessionId}&amp;sql=@HISTORY" target="h2result"
><img src="icon_history.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.toolbar.history}" title="${text.toolbar.history}" border="1"/></a
class="icon" alt="${text.toolbar.history}" title="${text.toolbar.history}" border="1"></a
><img src="icon_line.gif" class="iconLine" alt=""
/></td><td class="toolbar">${text.toolbar.autocomplete}&nbsp;<select name="autocomplete" size="1"
></td><td class="toolbar">${text.toolbar.autocomplete}&nbsp;<select name="autocomplete" size="1"
onchange="javascript:top.frames['h2query'].setAutocomplete(this.value)"
><option value="0">${text.toolbar.autocomplete.off}</option>
<option selected="selected" value="1">${text.toolbar.autocomplete.normal}</option>
......@@ -80,7 +80,7 @@ Initial Developer: H2 Group
><img src="icon_help.gif"
onmouseover = "this.className ='icon_hover'"
onmouseout = "this.className ='icon'"
class="icon" alt="${text.a.help}" title="${text.a.help}" border="1"/></a
class="icon" alt="${text.a.help}" title="${text.a.help}" border="1"></a
></td></tr></table>
</form>
<script type="text/javascript">
......
......@@ -72,9 +72,11 @@ function set(s) {
</td></tr>
</table>
<h3>${text.helpAddDrivers}</h3>
${text.helpAddDriversText}
<p>
${text.helpAddDriversText}
</p><p>
${text.helpAddDriversOnlyJava}
</p>
</div>
......
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -20,4 +20,4 @@ Javascript is currently disabled or your browser does not support Javascript.
For this application to work, Javascript is essential.
Please enable Javascript now, or use another web browser that supports it.
</body>
</body></html>
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.login.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -83,4 +83,4 @@ Initial Developer: H2 Group
<br>
<p class="error">${error}</p>
</form>
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
......@@ -26,4 +26,4 @@ Initial Developer: H2 Group
<h2><a href="admin.jsp">Preferences</a></h2>
Allows to you to view and change server settings.
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<head>
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
</head>
......@@ -12,4 +12,4 @@ Initial Developer: H2 Group
<p>
${text.a.remoteConnectionsDisabled}
</p>
</body>
\ No newline at end of file
</body></html>
\ No newline at end of file
......@@ -5,9 +5,9 @@ Initial Developer: H2 Group
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>${text.a.title}</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script type="text/javascript">
//<!--
......
......@@ -48,7 +48,7 @@ public class Newsfeed {
s = StringUtils.replaceAll(s, "<a href=\"", "( ");
s = StringUtils.replaceAll(s, "\">", " ) ");
s = StringUtils.replaceAll(s, "</a>", "");
s = StringUtils.replaceAll(s, "<br/>", "");
s = StringUtils.replaceAll(s, "<br>", "");
if(s.indexOf('<') >= 0 || s.indexOf('>') >= 0) {
throw new Error("Unsupported HTML Tag: < or > in " + s);
}
......
......@@ -93,7 +93,7 @@ public class GenerateDoc {
String topic = rs.getString("TOPIC");
String syntax = rs.getString("SYNTAX");
syntax = bnf.getSyntax(topic, syntax);
map.put("syntax", syntax);
map.put("syntax", PageParser.escapeHtml(syntax));
list.add(map);
}
session.put(key, list);
......
......@@ -85,7 +85,7 @@ public class LinkChecker {
}
void process(String path) throws Exception {
if(path.endsWith("/CVS")) {
if(path.endsWith("/CVS") || path.endsWith("/.svn")) {
return;
}
File file = new File(path);
......
/*
* 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.tools.doc;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.util.Stack;
public class XMLChecker {
public static void main(String[] args) throws Exception {
new XMLChecker().run(args);
}
private void run(String[] args) throws Exception {
String dir = ".";
for(int i=0; i<args.length; i++) {
if("-dir".equals(args[i])) {
dir = args[++i];
}
}
process(dir+"/src");
process(dir+"/docs");
}
void process(String path) throws Exception {
if(path.endsWith("/CVS") || path.endsWith("/.svn")) {
return;
}
File file = new File(path);
if(file.isDirectory()) {
String[] list = file.list();
for(int i=0; i<list.length; i++) {
process(path + "/" + list[i]);
}
} else {
processFile(path);
}
}
void processFile(String fileName) throws Exception {
int idx = fileName.lastIndexOf('.');
if(idx < 0) {
return;
}
String suffix = fileName.substring(idx + 1);
if(!suffix.equals("html") && !suffix.equals("xml") && !suffix.equals("jsp")) {
return;
}
System.out.println("Checking file:" + fileName);
FileReader reader = new FileReader(fileName);
String s = readStringAndClose(reader, -1);
Exception last = null;
try {
checkXML(s, !suffix.equals("xml"));
} catch(Exception e) {
last = e;
System.out.println("ERROR: " + e.toString());
}
if(last != null) {
last.printStackTrace();
}
}
public static String readStringAndClose(Reader in, int length) throws IOException {
if(length <= 0) {
length = Integer.MAX_VALUE;
}
int block = Math.min(4096, length);
StringWriter out=new StringWriter(length == Integer.MAX_VALUE ? block : length);
char[] buff=new char[block];
while(length > 0) {
int len = Math.min(block, length);
len = in.read(buff, 0, len);
if(len < 0) {
break;
}
out.write(buff, 0, len);
length -= len;
}
in.close();
return out.toString();
}
private static void checkXML(String xml, boolean html) throws Exception {
String lastElement = null;
String[] noclose = new String[]{
"li", "link", "meta", "br", "img", "input", "hr", "frame"
};
XMLParser parser = new XMLParser(xml);
Stack stack = new Stack();
boolean rootElement = false;
while(true) {
int event = parser.next();
if(event == XMLParser.END_DOCUMENT) {
break;
} else if(event == XMLParser.START_ELEMENT) {
if(stack.size() == 0) {
if(rootElement) {
throw new Exception("Second root element at " + parser.getRemaining());
}
rootElement = true;
}
String name = parser.getName();
if(html && name.equals("table") && lastElement.trim().length() > 0) {
throw new Exception("Test before table: " + lastElement);
}
for(int i=0; html && i<noclose.length; i++) {
if(name.equals(noclose[i])) {
name = null;
break;
}
}
if(name != null) {
stack.add(name);
}
} else if(event == XMLParser.END_ELEMENT) {
String name = parser.getName();
for(int i=0; html && i<noclose.length; i++) {
if(name.equals(noclose[i])) {
throw new Exception("Unnecessary closing element " + name + " at " + parser.getRemaining());
}
}
while(true) {
String pop = (String) stack.pop();
if(pop.equals(name)) {
break;
}
throw new Exception("Unclosed element " + pop + " at " + parser.getRemaining());
}
} else if(event == XMLParser.CHARACTERS) {
lastElement = parser.getText();
} else if(event == XMLParser.DTD) {
} else if(event == XMLParser.COMMENT) {
} else {
int eventType = parser.getEventType();
throw new Exception("Unexpected event " + eventType + " at " + parser.getRemaining());
}
}
if(stack.size() != 0) {
throw new Exception("Unclosed root element");
}
}
}
/*
* 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.tools.doc;
public class XMLParser {
public static final int ERROR = 0;
public static final int START_ELEMENT=1;
public static final int END_ELEMENT=2;
public static final int PROCESSING_INSTRUCTION=3;
public static final int CHARACTERS=4;
public static final int COMMENT=5;
public static final int SPACE=6;
public static final int START_DOCUMENT=7;
public static final int END_DOCUMENT=8;
public static final int ENTITY_REFERENCE=9;
public static final int ATTRIBUTE=10;
public static final int DTD=11;
public static final int CDATA=12;
public static final int NAMESPACE=13;
public static final int NOTATION_DECLARATION=14;
public static final int ENTITY_DECLARATION=15;
private String xml;
private int index;
private int eventType;
private String currentText;
private String prefix, localName;
private String[] attributeValues = new String[3];
private int currentAttribute;
private boolean endElement;
public XMLParser(String xml) {
this.xml = xml;
eventType = START_DOCUMENT;
}
void addAttributeName(String prefix, String localName) {
if(attributeValues.length <= currentAttribute) {
String[] temp = new String[attributeValues.length * 2];
System.arraycopy(attributeValues, 0, temp, 0, attributeValues.length);
attributeValues = temp;
}
attributeValues[currentAttribute++] = prefix;
attributeValues[currentAttribute++] = localName;
}
void addAttributeValue(String v) {
attributeValues[currentAttribute++] = v;
}
private int readChar() {
if (index >= xml.length()) {
return -1;
}
return xml.charAt(index++);
}
private void back() {
index--;
}
private void error(String expected) {
throw new Error("expected: " + expected + " got: " + xml.substring(index));
}
private void read(String chars) {
for (int i = 0; i < chars.length(); i++) {
if (readChar() != chars.charAt(i)) {
error(chars);
}
}
}
private void skipSpaces() {
while (index < xml.length() && xml.charAt(index) <= ' ') {
index++;
}
}
private void read() {
currentText = null;
currentAttribute = 0;
int currentStart = index;
int ch = readChar();
if (ch < 0) {
eventType = END_DOCUMENT;
return;
}
if (ch == '<') {
currentStart = index;
ch = readChar();
if (ch < 0) {
eventType = ERROR;
return;
} else if (ch == '?') {
eventType = PROCESSING_INSTRUCTION;
currentStart = index;
while (true) {
ch = readChar();
if (ch < 0) {
error("?>");
}
if (ch == '?' && readChar() == '>') {
break;
}
}
if(xml.substring(currentStart).startsWith("xml")) {
read();
return;
}
currentText = xml.substring(currentStart, index - 1);
} else if (ch == '!') {
ch = readChar();
if (ch == '-') {
eventType = COMMENT;
if (readChar() != '-') {
error("-");
}
currentStart = index;
while (true) {
ch = readChar();
if (ch < 0) {
error("-->");
}
if (ch == '-' && readChar() == '-') {
read(">");
break;
}
}
currentText = xml.substring(currentStart, index - 1);
} else if (ch == 'D') {
read("OCTYPE");
eventType = DTD;
while (true) {
ch = readChar();
if (ch < 0) {
break;
}
if (ch == '>') {
break;
}
}
} else if(ch == '[') {
read("CDATA[");
currentStart = index;
eventType = CHARACTERS;
while(true) {
ch = readChar();
if(ch < 0) {
error("]]>");
} else if(ch != ']') {
continue;
}
ch = readChar();
if(ch < 0) {
error("]]>");
} else if(ch == ']') {
do {
ch = readChar();
if(ch < 0) {
error("]]>");
}
} while(ch == ']');
if(ch == '>') {
currentText = xml.substring(currentStart, index - 3);
break;
}
}
}
}
} else if(ch == '/') {
currentStart = index;
prefix = null;
eventType = END_ELEMENT;
while (true) {
ch = readChar();
if (ch < 0) {
error(">");
} else if(ch == ':') {
prefix = xml.substring(currentStart, index - 1);
currentStart = index + 1;
} else if(ch == '>') {
localName = xml.substring(currentStart, index - 1);
break;
} else if(ch <= ' ') {
localName = xml.substring(currentStart, index - 1);
skipSpaces();
read(">");
break;
}
}
} else {
prefix = null;
localName = null;
eventType = START_ELEMENT;
while (true) {
ch = readChar();
if (ch < 0) {
error(">");
} else if(ch == ':') {
prefix = xml.substring(currentStart, index - 1);
currentStart = index + 1;
} else if (ch <= ' ') {
localName = xml.substring(currentStart, index - 1);
readAttributeValues();
ch = readChar();
}
if (ch == '/') {
if(localName == null) {
localName = xml.substring(currentStart, index - 1);
}
read(">");
endElement = true;
break;
} else if(ch == '>') {
if(localName == null) {
localName = xml.substring(currentStart, index - 1);
}
break;
}
}
}
} else {
eventType = CHARACTERS;
while (true) {
ch = readChar();
if(ch < 0) {
break;
} else if(ch == '<') {
back();
break;
}
}
currentText = xml.substring(currentStart, index);
}
}
private void readAttributeValues() {
while(true) {
int start = index;
int ch = readChar();
if(ch < 0) {
error(">");
} else if(ch <= ' ') {
continue;
} else if(ch == '/' || ch == '>') {
back();
return;
}
int end;
int localNameStart = start;
while(true) {
end = index;
ch = readChar();
if(ch < 0) {
error("=");
} else if(ch <= ' ') {
skipSpaces();
ch = readChar();
if(ch != '=') {
error("=");
}
break;
} else if(ch == '=') {
break;
} else if(ch == ':') {
localNameStart = index;
}
}
if(localNameStart == start) {
addAttributeName("", xml.substring(localNameStart, end));
} else {
addAttributeName(xml.substring(start, localNameStart - 1), xml.substring(localNameStart, end));
}
skipSpaces();
ch = readChar();
if(ch != '\"') {
error("\"");
}
start = index;
while(true) {
end = index;
ch = readChar();
if(ch < 0) {
error("\"");
} else if(ch == '\"') {
break;
}
}
addAttributeValue(xml.substring(start, end));
}
}
public boolean hasNext() {
return index < xml.length();
}
public int next() {
if(endElement) {
endElement = false;
eventType = END_ELEMENT;
} else {
read();
}
return eventType;
}
public int nextTag() {
while (true) {
int type = next();
if (type != COMMENT && type != DTD && type != PROCESSING_INSTRUCTION) {
return type;
}
}
}
public int getEventType() {
return eventType;
}
public String getText() {
return currentText;
}
public int getAttributeCount() {
return currentAttribute / 3;
}
public String getAttributePrefix(int index) {
return attributeValues[index * 3];
}
public String getAttributeLocalName(int index) {
return attributeValues[index * 3 + 1];
}
public String getAttributeName(int index) {
String prefix = getAttributePrefix(index);
String localName = getAttributeLocalName(index);
return prefix == null || prefix.length() == 0 ? localName : prefix + ":" + localName;
}
public String getAttributeValue(int index) {
return attributeValues[index * 3 + 2];
}
public String getAttributeValue(String namespaceURI, String localName) {
int len = getAttributeCount();
for(int i=0; i<len; i ++) {
if(getAttributeLocalName(i).equals(localName)) {
return getAttributeValue(i);
}
}
return null;
}
public String getName() {
return prefix == null || prefix.length() == 0 ? localName : prefix + ":" + localName;
}
public String getLocalName() {
return localName;
}
public String getPrefix() {
return prefix;
}
public boolean isWhiteSpace() {
return getText().trim().length() == 0;
}
public String getRemaining() {
return xml.substring(index);
}
}
......@@ -61,7 +61,7 @@ public class Doclet {
writer.println("<table class=\"content\"><tr class=\"content\"><td class=\"content\"><div class=\"contentDiv\">");
writer.println("<h1>"+className+"</h1>");
writer.println(clazz.commentText()+"<br /><br />");
writer.println(clazz.commentText()+"<br><br>");
MethodDoc[] methods = clazz.methods();
Arrays.sort(methods, new Comparator() {
......@@ -117,7 +117,7 @@ public class Doclet {
continue;
}
if(fieldId==0) {
writer.println("<br /><table><tr><th colspan=\"2\">Fields</th></tr>");
writer.println("<br><table><tr><th colspan=\"2\">Fields</th></tr>");
}
String name = field.name();
String type = getTypeName(true, field.type());
......@@ -174,7 +174,7 @@ public class Doclet {
boolean space = false;
for(int j=0; j<paramTags.length; j++) {
if(!space) {
writer.println("<br /><br >");
writer.println("<br><br >");
space = true;
}
String p = paramTags[j].parameterName() + " - " + paramTags[j].parameterComment();
......@@ -186,7 +186,7 @@ public class Doclet {
Tag[] returnTags = method.tags("return");
if(returnTags != null && returnTags.length>0) {
if(!space) {
writer.println("<br /><br >");
writer.println("<br><br >");
space = true;
}
writer.println("<div class=\"itemTitle\">Returns:</div>");
......@@ -195,7 +195,7 @@ public class Doclet {
ThrowsTag[] throwsTags = method.throwsTags();
if(throwsTags != null && throwsTags.length > 0) {
if(!space) {
writer.println("<br /><br >");
writer.println("<br><br >");
space = true;
}
writer.println("<div class=\"itemTitle\">Throws:</div>");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论