Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
b4232f24
提交
b4232f24
authored
4月 18, 2009
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improved documentation
上级
e584183b
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
213 行增加
和
178 行删除
+213
-178
features.html
h2/src/docsrc/html/features.html
+156
-162
Mode.java
h2/src/main/org/h2/engine/Mode.java
+10
-10
Compact.java
h2/src/test/org/h2/samples/Compact.java
+2
-1
Function.java
h2/src/test/org/h2/samples/Function.java
+38
-3
TaskProcess.java
h2/src/test/org/h2/test/db/TaskProcess.java
+5
-0
TestSampleApps.java
h2/src/test/org/h2/test/unit/TestSampleApps.java
+1
-1
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+1
-1
没有找到文件。
h2/src/docsrc/html/features.html
浏览文件 @
b4232f24
...
...
@@ -39,8 +39,8 @@ Features
Database File Locking
</a><br
/>
<a
href=
"#database_only_if_exists"
>
Opening a Database Only if it Already Exists
</a><br
/>
<a
href=
"#closing_
the
_database"
>
Closing
the
Database
</a><br
/>
<a
href=
"#closing_
a
_database"
>
Closing
a
Database
</a><br
/>
<a
href=
"#ignore_unknown_settings"
>
Ignore Unknown Settings
</a><br
/>
<a
href=
"#other_settings"
>
...
...
@@ -627,13 +627,13 @@ class loader environment.
</p><p>
It is also possible to access a memory-only database remotely
(or from multiple processes in the same machine) 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).
An example database URL is:
<code>
jdbc:h2:tcp://localhost/mem:db1
</code>
.
</p><p>
By default, when the last connection to a in-memory database is closed, the contents are lost.
This can be disabled by adding ;DB_CLOSE_DELAY=-1 to the database URL. That means to keep
the contents of an in-memory database as long as the virtual machine is alive, use
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
By default, closing the last connection to a database closes the database.
For an in-memory database, this means the content is lost.
To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL.
To keep the content of an in-memory database as long as the virtual machine is alive, use
<code>
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
</code>
.
</p>
<br
/><a
name=
"file_encryption"
></a>
...
...
@@ -653,9 +653,9 @@ To create an encrypted database, connect to it as it would already exist.
<h3>
Connecting to an Encrypted Database
</h3>
<p>
The encryption algorithm is set in the database URL, and the file password is specified in the password field,
before the user password. A single space
needs to be added between
the file password
before the user password. A single space
separates
the file password
and the user password; the file password itself may not contain spaces. File passwords
(as well as user passwords)
are case sensitive. Here is an example to connect to a
and user passwords
are case sensitive. Here is an example to connect to a
password-encrypted database:
</p>
<pre>
...
...
@@ -669,9 +669,9 @@ conn = DriverManager.
<h3>
Encrypting or Decrypting a Database
</h3>
<p>
If you want t
o encrypt an existing database, use the ChangeFileEncryption tool.
T
o encrypt an existing database, use the ChangeFileEncryption tool.
This tool can also decrypt an encrypted database, or change the file encryption key.
It
is available from within the H2 Console in the Tools section, or you can run it from the command line.
The tool
is available from within the H2 Console in the Tools section, or you can run it from the command line.
The following command line will encrypt the database 'test' in the user home directory
with the file password 'filepwd' and the encryption algorithm AES:
</p>
...
...
@@ -693,7 +693,7 @@ The following file locking methods are implemented:
protect the database file. The watchdog reads the lock file each second.
</li><li>
The second method is 'socket' and opens a server socket. The socket method does
not require reading the lock file every second. The socket method should only be used
if the database files are only accessed by
the
one (and always the same) computer.
if the database files are only accessed by one (and always the same) computer.
</li><li>
It is also possible to open the database without file locking;
in this case it is up to the application to protect the database files.
</li></ul>
...
...
@@ -713,18 +713,18 @@ data corruption:
String url = "jdbc:h2:~/test;FILE_LOCK=NO";
</pre>
<p>
For more information about the algorithms
please see in Advanced Topics under
File Locking Protocol
.
For more information about the algorithms
, see
<a
href=
"advanced.html#file_locking_protocols"
>
Advanced / File Locking Protocols
</a>
.
</p>
<br
/><a
name=
"database_only_if_exists"
></a>
<h2>
Opening a Database Only if it Already Exists
</h2>
<p>
By default, when an application calls
<code>
DriverManager.getConnection(url,...)
</code>
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.
In some situations, it is better to restrict creating new database
, and only
open
the database if it already exists. This can be done by adding
<code>
;ifexists=true
</code>
to the URL. In this case, if the database does not already exist, an exception is thrown when
In some situations, it is better to restrict creating new database
s, and only allow to
open
existing databases. To do this, add
<code>
;ifexists=true
</code>
to the
database
URL. In this case, if the database does not already exist, an exception is thrown when
trying to connect. The connection only succeeds when the database already exists.
The complete URL may look like this:
</p>
...
...
@@ -732,33 +732,33 @@ The complete URL may look like this:
String url = "jdbc:h2:/data/sample;IFEXISTS=TRUE";
</pre>
<br
/><a
name=
"closing_
the
_database"
></a>
<h2>
Closing
the
Database
</h2>
<br
/><a
name=
"closing_
a
_database"
></a>
<h2>
Closing
a
Database
</h2>
<h3>
Delayed Database Closing
</h3>
<p>
Usually,
the
database is closed when the last connection to it is closed. In some situations
this slows down the application, for example when it is not possible
leave th
e connection open.
The automatic closing of
the
database can be delayed or disabled with the SQL statement
SET DB_CLOSE_DELAY
<
seconds
>
. The
seconds
specifies the number of seconds to keep
a database open after the last connection to it was closed.
For example t
he following statement
will keep
the database open for 10 seconds
:
Usually,
a
database is closed when the last connection to it is closed. In some situations
this slows down the application, for example when it is not possible
to keep at least on
e connection open.
The automatic closing of
a
database can be delayed or disabled with the SQL statement
SET DB_CLOSE_DELAY
<
seconds
>
. The
parameter
<
seconds
>
specifies the number of seconds to keep
a database open after the last connection to it was closed.
T
he following statement
will keep
a database open for 10 seconds after the last connection was closed
:
</p>
<pre>
SET DB_CLOSE_DELAY 10
</pre>
<p>
The value -1 means the database is n
ever
closed automatically.
The value -1 means the database is n
ot
closed automatically.
The value 0 is the default and means the database is closed when the last connection is closed.
This setting is persistent and can be set by an administrator only.
It is possible to set the value in the database URL:
<code>
jdbc:h2:~/test;DB_CLOSE_DELAY=10
</code>
.
</p>
<br
/><a
name=
"do_not_close_on_exit"
></a>
<h3>
Don't Close
the
Database when the VM Exits
</h3>
<h3>
Don't Close
a
Database when the VM Exits
</h3>
<p>
By default, a database is closed when the last connection is closed. However, if it is never closed,
the database is closed when the virtual machine exits normally
. This is done
using a shutdown hook.
the database is closed when the virtual machine exits normally
,
using a shutdown hook.
In some situations, the database should not be closed in this case, for example because the
database is still used at virtual machine shutdown (to store the shutdown process in the database for example).
For those cases, the automatic closing of the database can be disabled in the database URL.
...
...
@@ -781,7 +781,7 @@ In some situations, for example when using very large databases (over a few hund
re-creating the index file takes very long.
In these situations it may be better to log changes to the index file,
so that recovery from a corrupted index file is fast.
To enable log index changes, add LOG=2 to the URL, as in
jdbc:h2:~/test;LOG=2
To enable log index changes, add LOG=2 to the URL, as in
<code>
jdbc:h2:~/test;LOG=2
</code>
.
This setting should be specified when connecting.
The update performance of the database will be reduced when using this option.
</p>
...
...
@@ -801,12 +801,11 @@ saying the parameter is not supported. It is possible to ignored such parameters
<br
/><a
name=
"other_settings"
></a>
<h2>
Changing Other Settings when Opening a Connection
</h2>
<p>
In addition to the settings already described
(cipher, file_lock, ifexists, user, password)
,
In addition to the settings already described,
other database settings can be passed in the database URL.
Adding
<code>
setting=value
</code>
at the end of an
URL is the
Adding
<code>
;setting=value
</code>
at the end of a database
URL is the
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.
connecting. For a list of supported settings, see
<a
href=
"grammar.html"
>
SQL Grammar
</a>
.
</p>
<br
/><a
name=
"custom_access_mode"
></a>
...
...
@@ -849,8 +848,8 @@ other processes (that could reside on other computers as well) connect to the se
<h3>
Multithreading Support
</h3>
<p>
This database is multithreading-safe. That means, if an application is multi-threaded, it does not need
o worry about synchronizing the
access to the database. Internally, most requests to the same database
are synchronized. That means an application can use multiple threads
accessing
the same database
to worry about synchronizing
access to the database. Internally, most requests to the same database
are synchronized. That means an application can use multiple threads
that access
the same database
at the same time, however if one thread executes a long running query, the other threads
need to wait.
</p>
...
...
@@ -861,17 +860,17 @@ The database uses table level locks to give each connection a consistent state o
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,
for the other connection to release the lock. If
a
connection cannot get a lock for a specified time,
then a lock timeout exception is thrown.
</p><p>
Usually, SELECT statement will generate read locks. This includes subqueries.
Usually, SELECT statement
s
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.
The statements COMMIT and ROLLBACK releases all open locks.
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
:
The following statements generate locks
:
</p>
<table>
<tr>
...
...
@@ -880,26 +879,26 @@ Here is an overview on what statements generate what type of lock:
</tr>
<tr>
<td>
Read
</td>
<td>
SELECT * FROM TEST
<br
/>
CALL SELECT MAX(ID) FROM TEST
<br
/>
SCRIPT
</td>
<td>
SELECT * FROM TEST
;
<br
/>
CALL SELECT MAX(ID) FROM TEST
;
<br
/>
SCRIPT
;
</td>
</tr>
<tr>
<td>
Write
</td>
<td>
SELECT * FROM TEST WHERE 1=0 FOR UPDATE
</td>
<td>
SELECT * FROM TEST WHERE 1=0 FOR UPDATE
;
</td>
</tr>
<tr>
<td>
Write
</td>
<td>
INSERT INTO TEST VALUES(1, 'Hello')
<br
/>
INSERT INTO TEST SELECT * FROM TEST
<br
/>
UPDATE TEST SET NAME='Hi'
<br
/>
DELETE FROM TEST
</td>
<td>
INSERT INTO TEST VALUES(1, 'Hello')
;
<br
/>
INSERT INTO TEST SELECT * FROM TEST
;
<br
/>
UPDATE TEST SET NAME='Hi'
;
<br
/>
DELETE FROM TEST
;
</td>
</tr>
<tr>
<td>
Write
</td>
<td>
ALTER TABLE TEST ...
<br
/>
CREATE INDEX ... ON TEST ...
<br
/>
DROP INDEX ...
</td>
<td>
ALTER TABLE TEST ...
;
<br
/>
CREATE INDEX ... ON TEST ...
;
<br
/>
DROP INDEX ...
;
</td>
</tr>
</table>
<p>
...
...
@@ -912,11 +911,11 @@ SET DEFAULT_LOCK_TIMEOUT <milliseconds>. The default lock timeout is persi
<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,
There are a number of files created for persistent databases.
Unlike some other
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).
In addition to that, a file is created for each large object (CLOB/BLOB)
, a file for each linear index
,
and temporary files for large result sets.
Then the command SCRIPT can create script files.
In addition to that, a file is created for each large object (CLOB/BLOB)
larger than a certain size
,
and temporary files for large result sets.
If the database trace option is enabled, trace files are created.
The following files can be created by the database:
</p>
...
...
@@ -924,8 +923,8 @@ The following files can be created by the database:
<tr><td>
test.data.db
</td><td>
Data file
<br
/>
Contains the data for all tables
<br
/>
Data file
.
<br
/>
Contains the data for all tables
.
<br
/>
Format:
<
database
>
.data.db
</td><td>
1 per database
...
...
@@ -933,8 +932,8 @@ The following files can be created by the database:
<tr><td>
test.index.db
</td><td>
Index file
<br
/>
Contains the data for all (b
tree) indexes
<br
/>
Index file
.
<br
/>
Contains the data for all (b
tree) indexes.
<br
/>
Format:
<
database
>
.index.db
</td><td>
1 per database
...
...
@@ -942,8 +941,8 @@ The following files can be created by the database:
<tr><td>
test.0.log.db
</td><td>
Log file
<br
/>
The
log file is used for recovery
<br
/>
Transaction log file.
<br
/>
The
transaction log is used for recovery.
<br
/>
Format:
<
database
>
.
<
id
>
.log.db
</td><td>
0 or more per database
...
...
@@ -951,8 +950,8 @@ The following files can be created by the database:
<tr><td>
test.lock.db
</td><td>
Database lock file
<br
/>
Exists only
if the database is open
<br
/>
Database lock file
.
<br
/>
Exists only
while the database is open.
<br
/>
Format:
<
database
>
.lock.db
</td><td>
1 per database
...
...
@@ -960,45 +959,36 @@ The following files can be created by the database:
<tr><td>
test.trace.db
</td><td>
Trace file
<br
/>
Contains trace information
<br
/>
Trace file
.
<br
/>
Contains trace information
.
<br
/>
Format:
<
database
>
.trace.db
<br
/>
If the file is too big, it is renamed to
<
database
>
.trace.db.old
</td><td>
1 per database
</td></tr>
<tr><td>
test.
14.
15.lob.db
test.
lobs.db/1.t
15.lob.db
</td><td>
Large object
<br
/>
Contains the data for BLOB or CLOB
<br
/>
Format:
<
database
>
.
<
tableid
>
.
<
i
d
>
.lob.db
Large object
.
<br
/>
Contains the data for BLOB or CLOB
values.
<br
/>
Format:
<
id
>
.t
<
tableI
d
>
.lob.db
</td><td>
1 per
object
1 per
value
</td></tr>
<tr><td>
test.123.temp.db
</td><td>
Temporary file
<br
/>
Contains a temporary blob or a large result set
<br
/>
Format:
<
database
>
.
<
session id
>
.
<
object
id
>
.temp.db
Temporary file
.
<br
/>
Contains a temporary blob or a large result set
.
<br
/>
Format:
<
database
>
.
<
id
>
.temp.db
</td><td>
1 per object
</td></tr>
<tr><td>
test.7.hash.db
</td><td>
Hash index file
<br
/>
Contains the data for a linear hash index
<br
/>
Format:
<
database
>
.
<
object id
>
.hash.db
</td><td>
1 per linear hash index
</td></tr>
</table>
<h3>
Moving and Renaming Database Files
</h3>
<p>
Database name and location are not stored inside the database
nam
es.
Database name and location are not stored inside the database
fil
es.
</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).
...
...
@@ -1049,14 +1039,14 @@ and tries to be compatible to other databases. There are still a few differences
<p>
In MySQL text columns are case insensitive by default, while in H2 they are case sensitive. However
H2 supports case insensitive columns as well. To create the tables with case insensitive texts, append
IGNORECASE=TRUE to the database URL (example:
jdbc:h2:~/test;IGNORECASE=TRUE
).
IGNORECASE=TRUE to the database URL (example:
<code>
jdbc:h2:~/test;IGNORECASE=TRUE
</code>
).
</p>
<h3>
Compatibility Modes
</h3>
<p>
For certain features, this database can emulate the behavior of specific databases.
Not all features or differences of those databases are implemented.
Here is the list of currently supported modes and the difference to the regular mode:
Here is the list of currently supported modes and the difference
s
to the regular mode:
</p>
<h3>
DB2 Compatibility Mode
</h3>
...
...
@@ -1067,7 +1057,7 @@ or the SQL statement <code>SET MODE DB2</code>.
<ul><li>
For aliased columns, ResultSetMetaData.getColumnName() returns the alias name
and getTableName() returns null.
</li><li>
Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY]
as an alternative
syntax
for LIMIT .. OFFSET.
as an alternative for LIMIT .. OFFSET.
</li></ul>
<h3>
Derby Compatibility Mode
</h3>
...
...
@@ -1089,9 +1079,9 @@ or the SQL statement <code>SET MODE HSQLDB</code>.
<ul><li>
For aliased columns, ResultSetMetaData.getColumnName() returns the alias name
and getTableName() returns null.
</li><li>
When converting the scale of decimal data, the number is only converted if the new scale is
smaller th
en
current scale. Usually, the scale is converted and 0s are added if required.
</li><li>
Concatenation
of a NULL with another value results in NULL. Usually, the
NULL is treated as an empty
string if only one of the opera
tors is NULL, and NULL is only returned if both value
s are NULL.
smaller th
an the
current scale. Usually, the scale is converted and 0s are added if required.
</li><li>
Concatenation
with NULL results in NULL. Usually,
NULL is treated as an empty
string if only one of the opera
nds is NULL, and NULL is only returned if both operand
s are NULL.
</li><li>
For unique indexes, NULL is distinct. That means only one row with NULL
in one of the columns is allowed.
</li></ul>
...
...
@@ -1116,10 +1106,10 @@ or the SQL statement <code>SET MODE MySQL</code>.
<ul><li>
When inserting data, if a column is defined to be NOT NULL and NULL is inserted,
then a 0 (or empty string, or the current timestamp for timestamp columns) value is used.
Usually, this operation is not allowed and an exception is thrown.
</li><li>
Creating indexes in the CREATE TABLE statement
should be support
ed.
</li><li>
The identifiers should be returned
in lower case.
</li><li>
When converting a floating point number to a integer, the fractional
digits
should not be truncated, but the value should be
rounded.
</li><li>
Creating indexes in the CREATE TABLE statement
is allow
ed.
</li><li>
Meta data calls return identifiers
in lower case.
</li><li>
When converting a floating point number to a
n
integer, the fractional
digits
are not truncated, but the value is
rounded.
</li></ul>
<h3>
Oracle Compatibility Mode
</h3>
...
...
@@ -1141,11 +1131,11 @@ or the SQL statement <code>SET MODE PostgreSQL</code>.
</p>
<ul><li>
For aliased columns, ResultSetMetaData.getColumnName() returns the alias name
and getTableName() returns null.
</li><li>
Concatenation
of a NULL with another value results in NULL. Usually, the
NULL is treated as an empty
string if only one of the opera
tors is NULL, and NULL is only returned if both value
s are NULL.
</li><li>
When converting a floating point number to a integer, the fractional
digits
should not be truncated, but the value should be
rounded.
</li><li>
The system columns 'CTID' and 'OID'
should b
e supported.
</li><li>
Concatenation
with NULL results in NULL. Usually,
NULL is treated as an empty
string if only one of the opera
nds is NULL, and NULL is only returned if both operand
s are NULL.
</li><li>
When converting a floating point number to a
n
integer, the fractional
digits
are not be truncated, but the value is
rounded.
</li><li>
The system columns 'CTID' and 'OID'
ar
e supported.
</li></ul>
<br
/><a
name=
"auto_reconnect"
></a>
...
...
@@ -1212,7 +1202,7 @@ where executed. This database offers the following trace features:
<li>
Trace to System.out and/or a file
</li><li>
Support for trace levels OFF, ERROR, INFO, and DEBUG
</li><li>
The maximum size of the trace file can be set
</li><li>
The Java code generation is possib
le
</li><li>
It is possible to generate Java source code from the trace fi
le
</li><li>
Trace can be enabled at runtime by manually creating a file
</li></ul>
...
...
@@ -1240,11 +1230,11 @@ SET TRACE_LEVEL_SYSTEM_OUT 3
<h3>
Setting the Maximum Size of the Trace File
</h3>
<p>
When using a high trace level, the trace file can get very big quickly.
The size of the file can be limited by executing the SQL statement
<code>
SET TRACE_MAX_FILE_SIZE maximumFileSizeInMB
</code>
.
If the log file exceeds the limit, the file is renamed to .old and a new file is created.
The default size limit is 16 MB, if the trace file exceeds this limit, it is renamed to .old and a new file is created.
If another .old file exists, it is deleted.
The default setting is 16 MB. Example:
The size limit can be changed using the SQL statement
<code>
SET TRACE_MAX_FILE_SIZE maximumFileSizeInMB
</code>
.
Example:
</p>
<pre>
SET TRACE_MAX_FILE_SIZE 1
...
...
@@ -1252,8 +1242,8 @@ SET TRACE_MAX_FILE_SIZE 1
<h3>
Java Code Generation
</h3>
<p>
When setting the trace level to INFO or DEBUG, Java source code is generated as well
, so that
problem can be reproduced
more easily. The trace file looks like this:
When setting the trace level to INFO or DEBUG, Java source code is generated as well
.
This allows to reproduce problems
more easily. The trace file looks like this:
</p>
<pre>
...
...
...
@@ -1264,24 +1254,17 @@ problem can be reproduced more easily. The trace file looks like this:
...
</pre>
<p>
You need to filter out the lines without /**/ to get the Java source code.
In Windows, a simple way to do that is:
To filter the Java source code, use the ConvertTraceFile tool as follows:
</p>
<pre>
find "**" test.trace.db > Trace.java
java -cp h2*.jar org.h2.tools.ConvertTraceFile
-traceFile "~/test.trace.db" -javaClass "Test"
</pre>
<p>
Afterwards, you need to complete the file Trace.java before it can be compiled, for example with:
</p>
<pre>
import java.sql.*;
public class Trace { public static void main(String[]a)throws Exception {
Class.forName("org.h2.Driver");
...
}}
</pre>
<p>
Also, the user name and password needs to be set, because they are not listed in the trace file.
The generated file
<code>
Test.java
</code>
will contain the Java source code.
The generated source code may be too large to compile (the size of a Java method is limited).
If this is the case, the source code needs to be split in multiple methods.
The password is not listed in the trace file and therefore not included in the source code.
</p>
<br
/><a
name=
"other_logging"
></a>
...
...
@@ -1309,7 +1292,7 @@ jdbc:h2:~/test;TRACE_LEVEL_FILE=4
Changing the log mechanism is not possible after the database is open, that means
executing the SQL statement SET TRACE_LEVEL_FILE 4 when the database is already open
will not have the desired effect. To use SLF4J, all required jar files need to be in the classpath.
If it does not work, check
in
the file
<
database
>
.trace.db for error messages.
If it does not work, check the file
<
database
>
.trace.db for error messages.
</p>
<br
/><a
name=
"read_only"
></a>
...
...
@@ -1317,18 +1300,18 @@ If it does not work, check in the file <database>.trace.db for error messa
<p>
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.
Only SELECT statements are allowed.
Only SELECT
and CALL
statements are allowed.
To create a read-only database, close the database so that the log file gets smaller. Do not delete the log file.
Then, make the database files read-only using the operating system.
When you open the database now, it is read-only.
There are two ways an application can find out
a
database is read-only:
There are two ways an application can find out
whether
database is read-only:
By calling Connection.isReadOnly() or by executing the SQL statement CALL READONLY().
</p>
<br
/><a
name=
"database_in_zip"
></a>
<h2>
Read Only Databases in Zip or Jar File
</h2>
<p>
To create a read-only database in a zip, first create a regular persistent database, and then create a backup.
To create a read-only database in a zip
file
, first create a regular persistent database, and then create a backup.
If you are using a database named 'test', an easy way to do that is using the Backup tool or the BACKUP SQL statement:
</p>
<pre>
...
...
@@ -1343,10 +1326,10 @@ and directly open the database in the zip file using the following database URL:
jdbc:h2:zip:~/data.zip!/test
</pre>
<p>
Databases in
a zip file
are read-only. The performance for some queries will be slower than when using
Databases in
zip files
are read-only. The performance for some queries will be slower than when using
a regular database, because random access in zip files is not supported (only streaming). How much this
affects the performance depends on the queries and the data. The database
is not read in memory;
so large databases are supported as well. The same indexes are used than
when using
is not read in memory;
therefore large databases are supported as well. The same indexes are used as
when using
a regular database.
</p>
...
...
@@ -1372,10 +1355,10 @@ The exceptions are logged, but opening the database will continue.
<br
/><a
name=
"computed_columns"
></a>
<h2>
Computed Columns / Function Based Index
</h2>
<p>
Function indexes are not directly supported by this database, but they can be e
asily e
mulated
Function indexes are not directly supported by this database, but they can be emulated
by using computed columns. For example, if an index on the upper-case version of
a column is required,
just
create a computed column with the upper-case version of the original column,
and
index
this column:
a column is required, create a computed column with the upper-case version of the original column,
and
create an index for
this column:
</p>
<pre>
CREATE TABLE ADDRESS(
...
...
@@ -1386,7 +1369,7 @@ CREATE TABLE ADDRESS(
CREATE INDEX IDX_U_NAME ON ADDRESS(UPPER_NAME);
</pre>
<p>
When inserting data, it is not required (
better:
not allowed) to specify a value for the upper-case
When inserting data, it is not required (
and
not allowed) to specify a value for the upper-case
version of the column, because the value is generated. But you can use the
column when querying the table:
</p>
...
...
@@ -1450,25 +1433,30 @@ This database supports using char arrays instead of String to pass user and file
The following code can be used to do that:
</p>
<pre>
Class.forName("org.h2.Driver");
String url = "jdbc:h2:~/simple";
String user = "sam";
char[] password =
{'t','i','a','S','
&
',E','t','r','p'};
Properties prop = new Properties();
prop.setProperty("user", user);
prop.put("password", password);
Connection conn = null;
try {
conn = DriverManager.
getConnection(url, prop);
} finally {
Arrays.fill(password, 0);
import java.sql.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
Class.forName("org.h2.Driver");
String url = "jdbc:h2:~/test";
Properties prop = new Properties();
prop.setProperty("user", "sa");
System.out.print("Password?");
char[] password = System.console().readPassword();
prop.put("password", password);
Connection conn = null;
try {
conn = DriverManager.getConnection(url, prop);
} finally {
Arrays.fill(password, (char) 0);
}
conn.close();
}
}
</pre>
<p>
In this example, the password is hard code in the application, which is not secure of course
.
However, Java Swing supports a way to get passwords using a char array (JPasswordField)
.
This example requires Java 1.6
.
When using Swing, use javax.swing.JPasswordField
.
</p>
<h3>
Passing the User Name and/or Password in the URL
</h3>
...
...
@@ -1496,8 +1484,8 @@ Only static Java methods are supported; both the class and the method must be pu
Example Java method:
</p>
<pre>
package
org.h2.samples
;
...
package
acme
;
import java.math.*;
public class Function {
public static boolean isPrime(int value) {
return new BigInteger(String.valueOf(value)).isProbablePrime(100);
...
...
@@ -1508,7 +1496,7 @@ public class Function {
The Java function must be registered in the database by calling CREATE ALIAS:
</p>
<pre>
CREATE ALIAS IS_PRIME FOR "
org.h2.samples
.Function.isPrime"
CREATE ALIAS IS_PRIME FOR "
acme
.Function.isPrime"
</pre>
<p>
For a complete sample application, see src/test/org/h2/samples/Function.java.
...
...
@@ -1517,14 +1505,16 @@ For a complete sample application, see src/test/org/h2/samples/Function.java.
<h3>
Function Data Type Mapping
</h3>
<p>
Functions that accept non-nullable parameters such as 'int' will not be called if one of those parameters is NULL.
In
this case, the value NULL is used as the result. If the function should be called in this case
, you need
In
stead, the result of the function is NULL. If the function should be called if a parameter is NULL
, you need
to use 'java.lang.Integer' instead of 'int'.
</p>
<h3>
Functions that require a Connection
</h3>
<p>
If the first parameter
in
a Java function is a java.sql.Connection, then the connection
If the first parameter
of
a Java function is a java.sql.Connection, then the connection
to database is provided. This connection does not need to be closed before returning.
When calling the method from within the SQL statement, this connection parameter
does not need to be (can not be) specified.
</p>
<h3>
Functions throwing an Exception
</h3>
...
...
@@ -1548,7 +1538,7 @@ CALL QUERY('SELECT * FROM TEST');
<h3>
Using SimpleResultSet
</h3>
<p>
A function
that returns a result set can create this result set from scratch
using the SimpleResultSet tool:
A function
can create a result set
using the SimpleResultSet tool:
</p>
<pre>
import org.h2.tools.SimpleResultSet;
...
...
@@ -1568,32 +1558,36 @@ CALL SIMPLE();
<h3>
Using a Function as a Table
</h3>
<p>
A function
returning a result set can be
like a table.
A function
that returns a result set can be used
like a table.
However, in this case the function is called at least twice:
First while parsing the statement to collect the column names
(with parameters set to null where not known at compile time).
And then, while executing the statement to get the data (may
be repeatedly
if this is a join).
And then, while executing the statement to get the data (may
be multiple times
if this is a join).
If the function is called just to get the column list, the URL of the connection passed to the function is
jdbc:columnlist:connection. Otherwise, the URL of the connection is jdbc:default:connection.
<code>
jdbc:columnlist:connection
</code>
. Otherwise, the URL of the connection is
<code>
jdbc:default:connection
</code>
.
</p>
<pre>
public static ResultSet getMatrix(Integer id) throws SQLException {
public static ResultSet getMatrix(Connection conn, Integer size)
throws SQLException {
SimpleResultSet rs = new SimpleResultSet();
rs.addColumn("X", Types.INTEGER, 10, 0);
rs.addColumn("Y", Types.INTEGER, 10, 0);
if(id == null) {
String url = conn.getMetaData().getURL();
if (url.equals("jdbc:columnlist:connection")) {
return rs;
}
for(int x = 0; x
<
id.intValue(); x++) {
for(int y = 0; y
<
id.intValue(); y++) {
rs.addRow(new Object[] { new Integer(x), new Integer(y) });
for (int s = size.intValue(), x = 0; x
<
s; x++) {
for (int y = 0; y
<
s; y++) {
rs.addRow(new Object[] {
new Integer(x), new Integer(y) });
}
}
return rs;
}
CREATE ALIAS MATRIX FOR "org.h2.samples.Function.getMatrix";
SELECT * FROM MATRIX(
3) WHERE X>0
;
SELECT * FROM MATRIX(
4) ORDER BY X, Y
;
</pre>
<br
/><a
name=
"triggers"
></a>
...
...
@@ -1609,8 +1603,8 @@ A Java trigger must implement the interface org.h2.api.Trigger:
import org.h2.api.Trigger;
...
public class TriggerSample implements Trigger {
public void init(
String triggerName, String tableName) {
}
public void init(
Connection conn, String schemaName, String triggerName,
String tableName, boolean before, int type) {
public void fire(Connection conn,
Object[] oldRow, Object[] newRow)
throws SQLException {
...
...
@@ -1626,7 +1620,7 @@ CREATE TRIGGER INV_INS AFTER INSERT ON INVOICE
FOR EACH ROW CALL "org.h2.samples.TriggerSample"
</pre>
<p>
The trigger can be used to veto a change, by throwing a SQL
Exception.
The trigger can be used to veto a change, by throwing a SQLException.
</p>
<br
/><a
name=
"compacting"
></a>
...
...
h2/src/main/org/h2/engine/Mode.java
浏览文件 @
b4232f24
...
...
@@ -44,31 +44,31 @@ public class Mode {
/**
* When converting the scale of decimal data, the number is only converted
* if the new scale is smaller th
en
current scale. Usually, the scale is
* if the new scale is smaller th
an the
current scale. Usually, the scale is
* converted and 0s are added if required.
*/
public
boolean
convertOnlyToSmallerScale
;
/**
* Creating indexes in the CREATE TABLE statement
should be support
ed.
* Creating indexes in the CREATE TABLE statement
is allow
ed.
*/
public
boolean
indexDefinitionInCreateTable
;
/**
*
The identifiers should be returned
in lower case.
*
Meta data calls return identifiers
in lower case.
*/
public
boolean
lowerCaseIdentifiers
;
/**
* Concatenation
of a NULL with another value results in NULL. Usually, the
*
NULL is treated as an empty string if only one of the operators is NULL,
*
and NULL is only returned if both value
s are NULL.
* Concatenation
with NULL results in NULL. Usually, NULL is treated as an
*
empty string if only one of the operands is NULL, and NULL is only
*
returned if both operand
s are NULL.
*/
public
boolean
nullConcatIsNull
;
/**
* When converting a floating point number to a integer, the fractional
* digits
should not be truncated, but the value should be
rounded.
* When converting a floating point number to a
n
integer, the fractional
* digits
are not truncated, but the value is
rounded.
*/
public
boolean
roundWhenConvertToLong
;
...
...
@@ -79,12 +79,12 @@ public class Mode {
/**
* Support for the syntax [OFFSET .. ROW] [FETCH ... ONLY]
* as an alternative
syntax
for LIMIT .. OFFSET.
* as an alternative for LIMIT .. OFFSET.
*/
public
boolean
supportOffsetFetch
;
/**
* The system columns 'CTID' and 'OID'
should b
e supported.
* The system columns 'CTID' and 'OID'
ar
e supported.
*/
public
boolean
systemColumns
;
...
...
h2/src/test/org/h2/samples/Compact.java
浏览文件 @
b4232f24
...
...
@@ -49,7 +49,8 @@ public class Compact {
* @param user the user name
* @param password the password
*/
public
static
void
compact
(
String
dir
,
String
dbName
,
String
user
,
String
password
)
throws
SQLException
{
public
static
void
compact
(
String
dir
,
String
dbName
,
String
user
,
String
password
)
throws
SQLException
{
String
url
=
"jdbc:h2:"
+
dir
+
"/"
+
dbName
;
String
file
=
"data/test.sql"
;
Script
.
execute
(
url
,
user
,
password
,
file
);
...
...
h2/src/test/org/h2/samples/Function.java
浏览文件 @
b4232f24
...
...
@@ -55,9 +55,19 @@ public class Function {
new
Integer
[]
{
new
Integer
(
30
),
new
Integer
(
20
)
});
prep
.
setObject
(
2
,
new
Integer
[]
{
new
Integer
(
1
),
new
Integer
(
2
)
});
ResultSet
rs2
=
prep
.
executeQuery
();
while
(
rs2
.
next
())
{
System
.
out
.
println
(
rs2
.
getInt
(
1
));
rs
=
prep
.
executeQuery
();
while
(
rs
.
next
())
{
System
.
out
.
println
(
rs
.
getInt
(
1
));
}
// Using a custom function like table
stat
.
execute
(
"CREATE ALIAS MATRIX FOR \"org.h2.samples.Function.getMatrix\" "
);
prep
=
conn
.
prepareStatement
(
"SELECT * FROM MATRIX(?) "
+
"ORDER BY X, Y"
);
prep
.
setInt
(
1
,
2
);
rs
=
prep
.
executeQuery
();
while
(
rs
.
next
())
{
System
.
out
.
println
(
rs
.
getInt
(
1
)
+
"/"
+
rs
.
getInt
(
2
));
}
conn
.
close
();
...
...
@@ -97,4 +107,29 @@ public class Function {
return
rs
;
}
/**
* Creates a simple result set with two columns.
*
* @param conn the connection
* @param size the number of x and y values
* @return the result set with two columns
*/
public
static
ResultSet
getMatrix
(
Connection
conn
,
Integer
size
)
throws
SQLException
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
rs
.
addColumn
(
"X"
,
Types
.
INTEGER
,
10
,
0
);
rs
.
addColumn
(
"Y"
,
Types
.
INTEGER
,
10
,
0
);
String
url
=
conn
.
getMetaData
().
getURL
();
if
(
url
.
equals
(
"jdbc:columnlist:connection"
))
{
return
rs
;
}
for
(
int
s
=
size
.
intValue
(),
x
=
0
;
x
<
s
;
x
++)
{
for
(
int
y
=
0
;
y
<
s
;
y
++)
{
rs
.
addRow
(
new
Object
[]
{
new
Integer
(
x
),
new
Integer
(
y
)
});
}
}
return
rs
;
}
}
h2/src/test/org/h2/test/db/TaskProcess.java
浏览文件 @
b4232f24
...
...
@@ -131,6 +131,11 @@ public class TaskProcess {
process
.
destroy
();
}
/**
* Trace the operation. Tracing is disabled by default.
*
* @param s the string to print
*/
private
void
traceOperation
(
String
s
)
{
// ignore
}
...
...
h2/src/test/org/h2/test/unit/TestSampleApps.java
浏览文件 @
b4232f24
...
...
@@ -46,7 +46,7 @@ public class TestSampleApps extends TestBase {
+
"PHONE: +41123456789\n\n"
+
"NAME: John Jones\n"
+
"EMAIL: john.jones@abcde.abc\n"
+
"PHONE: +41976543210\n"
);
testApp
(
org
.
h2
.
samples
.
Function
.
class
,
null
,
"2 is prime\n3 is prime\n5 is prime\n7 is prime\n11 is prime\n13 is prime\n17 is prime\n19 is prime\n30\n20"
);
"2 is prime\n3 is prime\n5 is prime\n7 is prime\n11 is prime\n13 is prime\n17 is prime\n19 is prime\n30\n20
\n0/0\n0/1\n1/0\n1/1
"
);
// Not compatible with PostgreSQL JDBC driver (throws a NullPointerException)
//testApp(org.h2.samples.SecurePassword.class, null, "Joe");
// TODO test ShowProgress (percent numbers are hardware specific)
...
...
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
b4232f24
...
...
@@ -586,4 +586,4 @@ soerensen favicon glass restarts flexive fish resulted vpda mvc kotek jan
consistently springfuse grep signatures wrote symbolic parents caches readers
animate scaladoc models disadvantages vladykin sergi trims requesting
handing bonita placed euros embeds reliability singular unregister quotas
overall httpdocs tigris eclemma
\ No newline at end of file
overall httpdocs tigris eclemma separates
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论